anvil-ruby 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.
@@ -0,0 +1,174 @@
1
+ # GitHub Actions Quick Reference
2
+
3
+ ## 🚀 Common Tasks
4
+
5
+ ### Publishing a New Version
6
+
7
+ ```bash
8
+ # 1. Update version in lib/anvil/version.rb
9
+ # 2. Update CHANGELOG.md
10
+ # 3. Commit and tag
11
+ git add -A
12
+ git commit -m "Release v0.2.0"
13
+ git tag v0.2.0
14
+ git push origin main --tags
15
+
16
+ # The gem will automatically be published to RubyGems
17
+ ```
18
+
19
+ ### Running CI Locally
20
+
21
+ ```bash
22
+ # Run all checks that CI runs
23
+ bundle exec rubocop # Linting
24
+ bundle exec rspec # Tests
25
+ bundle-audit check --update # Security audit
26
+ gem build *.gemspec # Build gem
27
+ ```
28
+
29
+ ### Debugging Failed Builds
30
+
31
+ ```bash
32
+ # View GitHub Actions logs
33
+ # 1. Go to: https://github.com/nickMarz/Ruby-Anvil/actions
34
+ # 2. Click on the failed workflow run
35
+ # 3. Click on the failed job to see logs
36
+
37
+ # Run specific Ruby version locally (using rbenv)
38
+ rbenv install 3.2.0
39
+ rbenv local 3.2.0
40
+ bundle install
41
+ bundle exec rspec
42
+
43
+ # Run with verbose output
44
+ bundle exec rspec --format documentation --backtrace
45
+ ```
46
+
47
+ ### Manual Workflow Triggers
48
+
49
+ ```bash
50
+ # Using GitHub CLI
51
+ gh workflow run ci.yml --ref main
52
+ gh workflow run gem-push.yml --ref main
53
+
54
+ # Or use the GitHub UI:
55
+ # Actions tab → Select workflow → Run workflow
56
+ ```
57
+
58
+ ## 📋 Required Secrets
59
+
60
+ | Secret | Where to Get | Required For |
61
+ |--------|--------------|--------------|
62
+ | `RUBYGEM_API_KEY` | [rubygems.org/profile/api_keys](https://rubygems.org/profile/api_keys) | Publishing gems |
63
+ | `ANVIL_API_KEY` | Anvil Dashboard | Running tests (optional) |
64
+
65
+ ## 🔧 Workflow Files
66
+
67
+ | File | Purpose | Triggers |
68
+ |------|---------|----------|
69
+ | `.github/workflows/ci.yml` | Tests, linting, security | Push, PR |
70
+ | `.github/workflows/gem-push.yml` | Publish to RubyGems | Version tags |
71
+ | `.github/dependabot.yml` | Dependency updates | Weekly |
72
+
73
+ ## 🏷️ Version Tags
74
+
75
+ ```bash
76
+ # Create a version tag
77
+ git tag v0.2.0
78
+
79
+ # Push tag to trigger gem publication
80
+ git push origin v0.2.0
81
+
82
+ # List all tags
83
+ git tag -l
84
+
85
+ # Delete a tag (if needed)
86
+ git tag -d v0.2.0
87
+ git push origin :refs/tags/v0.2.0
88
+ ```
89
+
90
+ ## 🔍 Status Checks
91
+
92
+ Before merging PRs, ensure these checks pass:
93
+ - ✅ Lint (RuboCop)
94
+ - ✅ Test (Ruby 2.7, 3.0, 3.1, 3.2, 3.3)
95
+ - ✅ Build
96
+ - ✅ Security
97
+
98
+ ## 🆘 Troubleshooting
99
+
100
+ ### RubyGems Publication Failed
101
+ ```bash
102
+ # Check if secret is set
103
+ # Settings → Secrets → Actions → RUBYGEM_API_KEY
104
+
105
+ # Verify API key permissions at rubygems.org
106
+ # Should have "Push rubygems" scope
107
+
108
+ # Test locally
109
+ gem push *.gem --key your_api_key
110
+ ```
111
+
112
+ ### Tests Pass Locally but Fail in CI
113
+ ```bash
114
+ # Check Ruby version
115
+ ruby -v
116
+
117
+ # Check for environment variables
118
+ env | grep ANVIL
119
+
120
+ # Use same bundler version
121
+ gem install bundler -v $(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -1 | tr -d ' ')
122
+ ```
123
+
124
+ ### Rate Limiting Issues
125
+ ```yaml
126
+ # Add to workflow if experiencing issues
127
+ - name: Wait to avoid rate limits
128
+ run: sleep 60
129
+ ```
130
+
131
+ ## 📊 Monitoring
132
+
133
+ - **Actions Dashboard**: [github.com/nickMarz/Ruby-Anvil/actions](https://github.com/nickMarz/Ruby-Anvil/actions)
134
+ - **Workflow Usage**: Settings → Billing & plans → Usage this month
135
+ - **Dependabot PRs**: Pull requests → Filter: `author:app/dependabot`
136
+
137
+ ## 🔐 Security
138
+
139
+ ```bash
140
+ # Run security audit locally
141
+ bundle-audit check --update
142
+
143
+ # Update vulnerable gems
144
+ bundle update gem_name
145
+
146
+ # Check for leaked secrets
147
+ # Never commit .env or credentials files!
148
+ git secrets --scan
149
+ ```
150
+
151
+ ## 📝 Useful Commands
152
+
153
+ ```bash
154
+ # See all GitHub CLI workflow commands
155
+ gh workflow --help
156
+
157
+ # List all workflows
158
+ gh workflow list
159
+
160
+ # View recent runs
161
+ gh run list
162
+
163
+ # Watch a run in progress
164
+ gh run watch
165
+
166
+ # View workflow file
167
+ gh workflow view ci.yml
168
+
169
+ # Download artifacts
170
+ gh run download [run-id]
171
+ ```
172
+
173
+ ---
174
+ *For detailed documentation, see [.github/workflows/README.md](.github/workflows/README.md)*
data/Gemfile.lock ADDED
@@ -0,0 +1,112 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ anvil-ruby (0.1.0)
5
+ base64
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.8.8)
11
+ public_suffix (>= 2.0.2, < 8.0)
12
+ ast (2.4.3)
13
+ base64 (0.3.0)
14
+ bigdecimal (4.0.1)
15
+ crack (1.0.1)
16
+ bigdecimal
17
+ rexml
18
+ diff-lcs (1.6.2)
19
+ docile (1.4.1)
20
+ hashdiff (1.2.1)
21
+ json (2.18.0)
22
+ language_server-protocol (3.17.0.5)
23
+ lint_roller (1.1.0)
24
+ multipart-post (2.4.1)
25
+ parallel (1.27.0)
26
+ parser (3.3.10.1)
27
+ ast (~> 2.4.1)
28
+ racc
29
+ prism (1.8.0)
30
+ public_suffix (5.1.1)
31
+ racc (1.8.1)
32
+ rainbow (3.1.1)
33
+ rake (13.3.1)
34
+ regexp_parser (2.11.3)
35
+ rexml (3.4.4)
36
+ rspec (3.13.2)
37
+ rspec-core (~> 3.13.0)
38
+ rspec-expectations (~> 3.13.0)
39
+ rspec-mocks (~> 3.13.0)
40
+ rspec-core (3.13.6)
41
+ rspec-support (~> 3.13.0)
42
+ rspec-expectations (3.13.5)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.13.0)
45
+ rspec-mocks (3.13.7)
46
+ diff-lcs (>= 1.2.0, < 2.0)
47
+ rspec-support (~> 3.13.0)
48
+ rspec-support (3.13.6)
49
+ rubocop (1.82.1)
50
+ json (~> 2.3)
51
+ language_server-protocol (~> 3.17.0.2)
52
+ lint_roller (~> 1.1.0)
53
+ parallel (~> 1.10)
54
+ parser (>= 3.3.0.2)
55
+ rainbow (>= 2.2.2, < 4.0)
56
+ regexp_parser (>= 2.9.3, < 3.0)
57
+ rubocop-ast (>= 1.48.0, < 2.0)
58
+ ruby-progressbar (~> 1.7)
59
+ unicode-display_width (>= 2.4.0, < 4.0)
60
+ rubocop-ast (1.49.0)
61
+ parser (>= 3.3.7.2)
62
+ prism (~> 1.7)
63
+ rubocop-capybara (2.22.1)
64
+ lint_roller (~> 1.1)
65
+ rubocop (~> 1.72, >= 1.72.1)
66
+ rubocop-factory_bot (2.28.0)
67
+ lint_roller (~> 1.1)
68
+ rubocop (~> 1.72, >= 1.72.1)
69
+ rubocop-rspec (2.31.0)
70
+ rubocop (~> 1.40)
71
+ rubocop-capybara (~> 2.17)
72
+ rubocop-factory_bot (~> 2.22)
73
+ rubocop-rspec_rails (~> 2.28)
74
+ rubocop-rspec_rails (2.29.1)
75
+ rubocop (~> 1.61)
76
+ ruby-progressbar (1.13.0)
77
+ simplecov (0.22.0)
78
+ docile (~> 1.1)
79
+ simplecov-html (~> 0.11)
80
+ simplecov_json_formatter (~> 0.1)
81
+ simplecov-html (0.13.2)
82
+ simplecov_json_formatter (0.1.4)
83
+ unicode-display_width (3.2.0)
84
+ unicode-emoji (~> 4.1)
85
+ unicode-emoji (4.2.0)
86
+ vcr (6.4.0)
87
+ webmock (3.26.1)
88
+ addressable (>= 2.8.0)
89
+ crack (>= 0.3.2)
90
+ hashdiff (>= 0.4.0, < 2.0.0)
91
+ yard (0.9.38)
92
+
93
+ PLATFORMS
94
+ arm64-darwin-24
95
+ ruby
96
+
97
+ DEPENDENCIES
98
+ anvil-ruby!
99
+ bundler (>= 1.17)
100
+ multipart-post (~> 2.3)
101
+ public_suffix (~> 5.0)
102
+ rake (>= 10.0)
103
+ rspec (~> 3.12)
104
+ rubocop (~> 1.50)
105
+ rubocop-rspec (~> 2.20)
106
+ simplecov (~> 0.22)
107
+ vcr (~> 6.1)
108
+ webmock (~> 3.18)
109
+ yard (~> 0.9)
110
+
111
+ BUNDLED WITH
112
+ 2.3.27
data/Gemfile.minimal ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Just the gem itself - no dev dependencies for now
4
+ gemspec
5
+
6
+ # Minimal test dependencies
7
+ group :test do
8
+ gem 'rspec', '~> 3.0'
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Nick Marazzo
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,196 @@
1
+ # Anvil Ruby Gem - Project Context
2
+
3
+ ## 🎯 Project Overview
4
+ Building a Ruby gem for the Anvil API (document automation and e-signatures) following Ruby best practices inspired by DHH and Matz.
5
+
6
+ **Repository:** https://github.com/nickMarz/Ruby-Anvil
7
+ **Current Version:** 0.1.0
8
+ **API Coverage:** ~30% implemented
9
+ **Ruby Version:** 3.4.8 (via rbenv)
10
+ **Development Approach:** Zero runtime dependencies using Net::HTTP
11
+
12
+ ## 📁 Key Files & Locations
13
+
14
+ ### Core Files
15
+ - `/Users/Nick.Marazzo/Documents/GitHub/anvil-ruby/` - Project root
16
+ - `.env` - Contains `ANVIL_API_KEY` and `ANVIL_TEMPLATE_ID`
17
+ - `.ruby-version` - Ruby 3.4.8
18
+ - `API_COVERAGE.md` - Comprehensive feature tracking (70% missing features documented)
19
+ - `PROJECT_CONTEXT.md` - This file (project reference)
20
+
21
+ ### Implementation Files
22
+ - `lib/anvil.rb` - Main entry point with configuration
23
+ - `lib/anvil/resources/pdf.rb` - PDF operations (fill, generate)
24
+ - `lib/anvil/resources/signature.rb` - E-signature implementation with GraphQL
25
+ - `lib/anvil/resources/webhook.rb` - Webhook parsing and verification
26
+ - `lib/anvil/env_loader.rb` - Custom .env loader (avoiding dependencies)
27
+ - `lib/anvil/client.rb` - HTTP client with rate limiting
28
+
29
+ ### Test Scripts
30
+ - `create_signature_direct.rb` - Direct GraphQL test (successfully created packet)
31
+ - `test_signature_with_template.rb` - Template-based signature test
32
+ - `test_etch_signature.rb` - E-signature connection testing
33
+
34
+ ## 🚀 Current Implementation Status
35
+
36
+ ### ✅ Implemented (30% of API)
37
+ 1. **PDF Operations**
38
+ - `PDF.fill` - Fill templates with JSON data
39
+ - `PDF.generate` - Generate from HTML/CSS or Markdown
40
+ - Save as file or base64
41
+
42
+ 2. **E-Signatures (Basic)**
43
+ - `Signature.create` - Create packets
44
+ - `Signature.find` - Find by ID
45
+ - `Signature.list` - List packets
46
+ - Signing URL generation
47
+ - Draft mode support
48
+
49
+ 3. **Webhooks**
50
+ - `Webhook.new` - Parse payloads
51
+ - `Webhook.valid?` - Verify authenticity
52
+ - Constant-time token validation
53
+
54
+ 4. **Infrastructure**
55
+ - Flexible API key configuration (3 methods)
56
+ - Rate limiting with exponential backoff
57
+ - Environment management (dev/production)
58
+ - Error handling with specific exception types
59
+
60
+ ### ❌ Missing (70% of API) - Tracked in GitHub
61
+
62
+ ## 📋 GitHub Organization
63
+
64
+ ### Milestones (3 phases)
65
+ 1. **Phase 1: Core Features (v0.2.0)** - Essential functionality
66
+ 2. **Phase 2: Advanced Features (v0.3.0)** - Advanced capabilities
67
+ 3. **Phase 3: AI & Enterprise (v0.4.0)** - AI and enterprise features
68
+
69
+ ### Issues Created (20 total)
70
+ - **8 parent issues** (#1-8) - High-level features
71
+ - **12 sub-issues** (#9-20) - Detailed implementation tasks
72
+
73
+ ### Project Board
74
+ - **URL:** https://github.com/users/nickMarz/projects/1
75
+ - **Name:** Anvil Ruby Gem Roadmap
76
+ - Linked to Ruby-Anvil repository
77
+ - Contains all 20 issues for tracking
78
+
79
+ ### Issue Breakdown
80
+
81
+ #### Phase 1 Issues
82
+ - #1: Generic GraphQL support
83
+ - #2: Complete e-signature features
84
+ - #9: Update packet mutation
85
+ - #10: Send packet from draft
86
+ - #11: Delete packet
87
+ - #12: Signer management
88
+ - #13: Void and expire operations
89
+ - #3: Basic workflow support
90
+ - #17: Workflow creation and retrieval
91
+ - #18: Workflow data submission
92
+ - #4: Basic webform support
93
+ - #19: Form creation and configuration
94
+ - #20: Form submission handling
95
+
96
+ #### Phase 2 Issues
97
+ - #5: Cast (PDF Template) management
98
+ - #6: Webhook management API
99
+ - #14: Webhook CRUD operations
100
+ - #15: Webhook actions management
101
+ - #16: Webhook logs and retry
102
+
103
+ #### Phase 3 Issues
104
+ - #7: Document AI/OCR capabilities
105
+ - #8: Organization management features
106
+
107
+ ## 🔧 Technical Details
108
+
109
+ ### API Endpoints
110
+ - REST API: `https://app.useanvil.com/api/v1/`
111
+ - GraphQL: `https://graphql.useanvil.com/` (NOTE: Full URL required, not just `/graphql`)
112
+
113
+ ### Authentication
114
+ - Basic Auth with API key as username, empty password
115
+ - Per-request API key override supported for multi-tenancy
116
+
117
+ ### Key Implementation Patterns
118
+ ```ruby
119
+ # Resource-based architecture (ActiveResource style)
120
+ class Signature < Resources::Base
121
+ def self.create(name:, signers:, files:, **options)
122
+ # GraphQL mutation implementation
123
+ end
124
+ end
125
+
126
+ # Flexible API key configuration
127
+ Anvil.api_key = "key" # Direct
128
+ ENV['ANVIL_API_KEY'] = "key" # Environment
129
+ config.api_key = "key" # Rails initializer
130
+
131
+ # Zero dependencies approach
132
+ # Using Net::HTTP instead of external HTTP gems
133
+ # Custom .env loader instead of dotenv gem
134
+ ```
135
+
136
+ ### GraphQL Mutations Structure
137
+ ```ruby
138
+ # Direct mutation parameters (not nested variables)
139
+ mutation = {
140
+ query: <<~GRAPHQL
141
+ mutation {
142
+ createEtchPacket(
143
+ name: "Test",
144
+ isDraft: true,
145
+ signers: [...]
146
+ ) { ... }
147
+ }
148
+ GRAPHQL
149
+ }
150
+ ```
151
+
152
+ ## 🐛 Known Issues & Fixes Applied
153
+
154
+ 1. **Ruby 3.4+ base64 extraction** - Added as explicit dependency
155
+ 2. **EnvLoader regex bug** - Fixed with `line.chomp`
156
+ 3. **GraphQL endpoint** - Must use full URL: `https://graphql.useanvil.com/`
157
+ 4. **HTTP path issue** - Include trailing slash in URI
158
+ 5. **Bundler compatibility** - Changed from `~> 2.0` to `>= 1.17`
159
+
160
+ ## 📝 Environment Variables
161
+ - `ANVIL_API_KEY` - Your Anvil API key
162
+ - `ANVIL_TEMPLATE_ID` - Template EID for testing (JlLOtzZKVNA1Mljsu999od)
163
+
164
+ ## 🎯 Next Steps
165
+ 1. Start with Issue #1 (Generic GraphQL support) as foundation
166
+ 2. Work through Phase 1 issues to reach v0.2.0
167
+ 3. Each sub-issue can be a separate PR
168
+ 4. Maintain zero dependencies principle
169
+ 5. Keep idiomatic Ruby style (predicates, bang methods)
170
+
171
+ ## 💡 Important Notes
172
+ - Gem follows Rails conventions but doesn't require Rails
173
+ - Emphasizes developer happiness (Matz's philosophy)
174
+ - Progressive disclosure: simple things simple, complex possible
175
+ - All new features should be additive (no breaking changes)
176
+ - Maintain comprehensive tests with RSpec
177
+ - Document with YARD comments
178
+
179
+ ## 📚 References
180
+ - [Anvil API Docs](https://www.useanvil.com/docs/)
181
+ - [GraphQL Reference](https://www.useanvil.com/docs/api/graphql/reference/)
182
+ - [GraphQL Schema](https://app.useanvil.com/graphql/sdl) (requires auth)
183
+ - [Ruby Gems Guide](https://guides.rubygems.org/make-your-own-gem/)
184
+
185
+ ## 🔄 Session Start Checklist
186
+ When starting a new session:
187
+ 1. Check this file for context
188
+ 2. Review `API_COVERAGE.md` for missing features
189
+ 3. Check GitHub project board for current status
190
+ 4. Verify environment with `ruby -v` (should be 3.4.8)
191
+ 5. Ensure .env has API keys loaded
192
+ 6. Run `bundle install` if needed
193
+
194
+ ---
195
+ *Last Updated: January 2024*
196
+ *Created for quick context when starting new Claude sessions*