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 +4 -4
- data/.gitignore +1 -0
- data/.reek.yml +3 -0
- data/CHANGELOG.md +6 -0
- data/CLAUDE.md +146 -0
- data/lib/business_flow/dsl.rb +3 -1
- data/lib/business_flow/version.rb +1 -1
- 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: 7e276f0e93f2f3b8e1467fdbdbe150b512963ae688afbf8675c0f29ae79b612f
|
|
4
|
+
data.tar.gz: 578abe1027f669c6feffdb8f57337d7efbc6dc7adf8fa9c29a7c5334d0bad85a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47519eef657f7b1b219a8f93ee7d979dd607b677e35d4225e3d3d59634637219627d790dbd5866a3b54d6872699aebef7e67147f3d6d10f1b3891d0e0fd83fc2
|
|
7
|
+
data.tar.gz: 3db5a8207caacb747847c7755f6f755ba0105a5fd1d2c0ade9671d254b63d7d20b157027c146ac10813ad9d4b5a009d39d7d4012923f70c83ca4567e643023d6
|
data/.gitignore
CHANGED
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
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)
|
data/lib/business_flow/dsl.rb
CHANGED
|
@@ -325,7 +325,9 @@ module BusinessFlow
|
|
|
325
325
|
end
|
|
326
326
|
|
|
327
327
|
def _business_flow_parameter_inner_fetch(key)
|
|
328
|
-
if @parameter_object.
|
|
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)
|
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.
|
|
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
|