business_flow 0.21.2 → 0.21.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efe077542fdb13fbaa9c53d3f58d108846e0b2bea1646a6789edeac73db8d9a7
4
- data.tar.gz: c4a74472e897c5c5dec78f7d87221adeaeb153fc3df9437cb86bb1c821672e75
3
+ metadata.gz: 7e276f0e93f2f3b8e1467fdbdbe150b512963ae688afbf8675c0f29ae79b612f
4
+ data.tar.gz: 578abe1027f669c6feffdb8f57337d7efbc6dc7adf8fa9c29a7c5334d0bad85a
5
5
  SHA512:
6
- metadata.gz: 855c34d54b1974dd8c3981843cd2f358b18021fac011f5f8042794f16f6ecb080bd7ffbaf837d364af575016e8dfe2ccb0766be21d4bdf8fa1e5f4d5c7dc8231
7
- data.tar.gz: bb0e099ed1105278c6460c4b681795c9f6fce62271734329aeda5d0cb4def5e521c1ba9435888b3d95b74ec1ca8e279b7bea52057e4f802b71d3e491cc29ddb2
6
+ metadata.gz: 47519eef657f7b1b219a8f93ee7d979dd607b677e35d4225e3d3d59634637219627d790dbd5866a3b54d6872699aebef7e67147f3d6d10f1b3891d0e0fd83fc2
7
+ data.tar.gz: 3db5a8207caacb747847c7755f6f755ba0105a5fd1d2c0ade9671d254b63d7d20b157027c146ac10813ad9d4b5a009d39d7d4012923f70c83ca4567e643023d6
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .claude/settings.local.json
data/.reek.yml CHANGED
@@ -14,5 +14,8 @@ detectors:
14
14
  # N.B. If we want to enable this, we need to tweak the RuboCop config. In particular, RuboCop
15
15
  # prefers `e` for exceptions.
16
16
  enabled: false
17
+ ManualDispatch:
18
+ exclude:
19
+ - BusinessFlow::DSL#_business_flow_parameter_inner_fetch
17
20
  exclude_paths:
18
21
  - vendor # For CircleCI.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.21.3
2
+
3
+ ENHANCEMENTS:
4
+
5
+ * Add compatibility with `ActionController::Parameters`
6
+
1
7
  ## 0.21.2
2
8
 
3
9
  BUG FIXES:
data/CLAUDE.md ADDED
@@ -0,0 +1,146 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ BusinessFlow is a Ruby gem providing a service object/workflow DSL built on ActiveModel. It manages complex business logic flows with validation, caching, retries, instrumentation, and distributed locking (via Zookeeper).
8
+
9
+ **Ruby:** >= 3.1.0 (project uses 3.3.9)
10
+ **Rails/ActiveModel:** 4.2 through 8.0
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ # Run full test suite
16
+ bundle exec rspec
17
+
18
+ # Run a single spec file
19
+ bundle exec rspec spec/business_flow/dsl_spec.rb
20
+
21
+ # Run a single example by line number
22
+ bundle exec rspec spec/business_flow/step_spec.rb:42
23
+
24
+ # Run tests against all supported ActiveModel versions
25
+ bundle exec appraisal rspec
26
+
27
+ # Run tests against a specific ActiveModel version
28
+ bundle exec appraisal activemodel-7.2 rspec
29
+
30
+ # Lint
31
+ bundle exec rubocop
32
+ bundle exec reek
33
+
34
+ # Autofix lint issues
35
+ bundle exec rubocop -A
36
+
37
+ # Interactive console with gem loaded
38
+ bin/console
39
+
40
+ # Setup (bundle install + appraisal install)
41
+ bin/setup
42
+ ```
43
+
44
+ ## Architecture
45
+
46
+ ### Flow Execution Pipeline
47
+
48
+ ```
49
+ include BusinessFlow::Base → DSL declares inputs/steps/outputs → .call(params)
50
+
51
+ Parameter validation (needs/optional/wants) → ActiveModel validations → Step queue execution → Result
52
+ ```
53
+
54
+ `BusinessFlow::Base` includes `DSL` and `Validations`. Most of the gem's logic lives in `DSL` and `Step`.
55
+
56
+ ### Core DSL (`lib/business_flow/dsl.rb`)
57
+
58
+ The largest file (~530 lines). Provides the class-level API:
59
+
60
+ - **Inputs:** `needs` (required), `optional`, `wants` (with defaults), `lookup` (dependency-based)
61
+ - **Steps:** `step(klass_or_proc, opts)` — adds to execution queue; supports `if:`/`unless:` conditions, `inputs:`/`outputs:` mappings
62
+ - **Outputs:** `provides` — fields exposed on the Result object
63
+ - **Computed fields:** `uses(field, klass)` — memoized, lazily-evaluated
64
+ - **Execution:** `.call(params)` returns a Result; `.call!` raises `FlowFailedException` on errors
65
+
66
+ Dynamically generates initializer methods (`finalize_initializer`) and per-flow Result classes (`finalize_result_provider`) via `class_eval`.
67
+
68
+ ### Step Execution (`lib/business_flow/step.rb`)
69
+
70
+ Steps marshal inputs from the flow, execute the callable, and merge outputs/errors back. Uses `throw :halt_step` / `catch(:halt_step)` for early termination on errors.
71
+
72
+ ### Callable Resolution (`lib/business_flow/callable.rb`)
73
+
74
+ Normalizes callables — symbols resolve to instance methods or constants, procs execute in instance context, classes with `.call` are invoked based on arity. Redefines dispatch methods after first call for performance.
75
+
76
+ ### Step Executors
77
+
78
+ Pluggable via `step_executor(klass)`:
79
+ - `DefaultStepExecutor` — sequential execution, halts on first error
80
+ - `InstrumentedExecutor` — adds flow-level ActiveSupport::Notifications
81
+ - `InstrumentedStepExecutor` — adds per-step notifications
82
+
83
+ ### Optional Mixins
84
+
85
+ - **`Cacheable`** — caches flow results; configurable store, TTL, and key generation
86
+ - **`Retryable`** — wraps execution in retry logic (uses `retryable` gem)
87
+ - **`Instrument`** — ActiveSupport::Notifications integration; `instrument_steps` for per-step events
88
+ - **`ClusterLock`** — distributed locking via Zookeeper
89
+
90
+ ### Version Compatibility (`lib/business_flow/compat.rb`)
91
+
92
+ Shims for `Module#module_parents` and `ActiveModel::Errors#merge!` across ActiveModel versions. `BusinessFlow.active_model5?` gates version-specific behavior.
93
+
94
+ ## Testing Conventions
95
+
96
+ - RSpec with `expect` syntax only (monkey patching disabled)
97
+ - SimpleCov with branch coverage
98
+ - `NotificationHelpers` module in spec_helper for testing ActiveSupport::Notifications
99
+ - Appraisals matrix tests against ActiveModel 4.2, 5.2, 6.1, 7.0, 7.1, 7.2, 8.0
100
+ - CircleCI runs rubocop, reek, and `appraisal rspec` across Ruby 3.1, 3.2, 3.3, 3.4
101
+
102
+ ## Style
103
+
104
+ - RuboCop with 100-char line limit (relaxed in specs)
105
+ - Reek for code smell detection
106
+ - `frozen_string_literal: true` in all files
107
+
108
+ ## Commit Message Format
109
+
110
+ Every commit must include a full human-Claude interaction log:
111
+
112
+ ```
113
+ Brief description of what was done
114
+
115
+ [Technical changes made]
116
+
117
+ ## Human-Claude Interaction Log
118
+
119
+ ### Human prompts (VERBATIM - include typos, informal language, COMPLETE text):
120
+ **Include EVERY prompt since last commit - even short ones, corrections, clarifications**
121
+ 1. "[Copy-paste ENTIRE first prompt since last commit]"
122
+ → Claude: [What Claude did in response]
123
+
124
+ 2. "[Copy-paste ENTIRE second prompt]"
125
+ → Claude: [How Claude adjusted]
126
+
127
+ [Continue numbering ALL prompts - don't skip any or judge importance]
128
+
129
+ ### Key decisions made:
130
+ - Human guided: [specific guidance provided]
131
+ - Claude discovered: [patterns found]
132
+
133
+ 🤖 Generated with Claude Code
134
+ Co-Authored-By: Claude <noreply@anthropic.com>
135
+ ```
136
+
137
+ Version bump commits use `v{VERSION}` as the first line (e.g. `v0.21.2`).
138
+
139
+ ## Release Process
140
+
141
+ 1. **Update version** in `lib/business_flow/version.rb`
142
+ 2. **Update `CHANGELOG.md`** — add a new version header with ENHANCEMENTS and/or BUG FIXES sections
143
+ 3. **Commit** the version bump and changelog (see commit format above)
144
+ 4. **Push** to origin — CircleCI will run the full test matrix (rubocop, reek, appraisal rspec across Ruby 3.1–3.4)
145
+ 5. **Verify CI passes** before releasing
146
+ 6. **Run `bundle exec rake release`** — this creates a `v{VERSION}` git tag, builds the gem, pushes the tag, and publishes to rubygems.org (requires MFA)
@@ -325,7 +325,9 @@ module BusinessFlow
325
325
  end
326
326
 
327
327
  def _business_flow_parameter_inner_fetch(key)
328
- if @parameter_object.is_a?(Hash) && @parameter_object.key?(key)
328
+ if @parameter_object.respond_to?(:key?) &&
329
+ @parameter_object.respond_to?(:[]) &&
330
+ @parameter_object.key?(key)
329
331
  @parameter_object[key]
330
332
  else
331
333
  @parameter_object.public_send(key)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BusinessFlow
4
- VERSION = '0.21.2'
4
+ VERSION = '0.21.3'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: business_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.2
4
+ version: 0.21.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Scarborough
@@ -64,6 +64,7 @@ files:
64
64
  - ".ruby-version"
65
65
  - ".travis.yml"
66
66
  - CHANGELOG.md
67
+ - CLAUDE.md
67
68
  - LICENSE.txt
68
69
  - README.md
69
70
  - Rakefile