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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 35685b6026edc34da7112bf2148651c92eb600741ebe34db0837cc83ef767754
4
+ data.tar.gz: 0b1cf1ec708c52f2820b6ad09423285d861fb2df103cc4122d5753fc1d42f11a
5
+ SHA512:
6
+ metadata.gz: eb8601c7824304fedc9d6be300dfc593ed764fccf9cc529b9b7cf283fee6a5bce85f4ff9e9e07573fd3dc496ea97a8c18379eb38bbbbe9e3455b198e6e127396
7
+ data.tar.gz: 8fcb0f0e5c1d3662b7dbc79391cadda9962c52723803027cdd19b8dc655944acadf34baff6333fe8baa3dcb9404d4eb46735f0c553ecda6f1ce701fe2619a6b0
data/AGENTS.md ADDED
@@ -0,0 +1,123 @@
1
+ # AGENTS.md
2
+
3
+ ## Project Overview
4
+
5
+ **anvil-ruby** is a Ruby gem providing a client for the [Anvil API](https://www.useanvil.com/docs/) — a document automation platform for PDF filling, PDF generation, e-signatures, and webhooks.
6
+
7
+ - **Version:** 0.1.0
8
+ - **Ruby:** >= 2.5.0 (developed on 3.4.8 via rbenv)
9
+ - **License:** MIT
10
+ - **Repo:** https://github.com/nickMarz/Ruby-Anvil
11
+ - **API coverage:** ~30% implemented
12
+
13
+ ## Commands
14
+
15
+ ```bash
16
+ bundle install # Install dependencies
17
+ bundle exec rspec # Run tests
18
+ bundle exec rspec --format documentation # Verbose test output
19
+ bundle exec rubocop # Lint / style check
20
+ bundle exec rake install # Install gem locally
21
+ gem build anvil-ruby.gemspec # Build the gem
22
+ ```
23
+
24
+ Always run `bundle exec rubocop` and `bundle exec rspec` before committing.
25
+
26
+ ## Architecture
27
+
28
+ ```
29
+ lib/
30
+ anvil.rb # Entry point, module-level configuration
31
+ anvil/
32
+ version.rb # VERSION constant
33
+ configuration.rb # Configuration class (api_key, environment, timeouts)
34
+ client.rb # HTTP client (Net::HTTP), auth, request building
35
+ errors.rb # Error hierarchy (APIError, ValidationError, etc.)
36
+ rate_limiter.rb # Retry with exponential backoff
37
+ response.rb # Response wrapper (JSON parsing, rate-limit headers)
38
+ env_loader.rb # Custom .env file parser (no dotenv dependency)
39
+ resources/
40
+ base.rb # Base resource class (ActiveRecord-like attributes)
41
+ pdf.rb # PDF.fill, PDF.generate, PDF.generate_from_html/markdown
42
+ signature.rb # Signature packets (create, find, list) via GraphQL
43
+ webhook.rb # Webhook parsing, token verification, decryption
44
+ ```
45
+
46
+ ### Key patterns
47
+
48
+ - **Resource-based architecture** — resources inherit from `Resources::Base` which provides attribute accessors via `method_missing`, serialization, and a class-level `client`.
49
+ - **Zero runtime dependencies** — only Ruby stdlib (`net/http`, `json`, `base64`, `uri`, `openssl`). The `base64` gem is added for Ruby 3.4+ compatibility.
50
+ - **GraphQL for signatures** — `Signature` resource posts to `https://graphql.useanvil.com/` (full URL, not relative path).
51
+ - **REST for PDFs** — `PDF` resource uses REST endpoints at `https://app.useanvil.com/api/v1/`.
52
+ - **Multi-tenancy** — per-request `api_key:` override on resource methods.
53
+ - **Configuration** — three methods: `Anvil.configure` block, `Anvil.api_key=`, or `ANVIL_API_KEY` env var.
54
+
55
+ ## Testing
56
+
57
+ - **Framework:** RSpec (with `--format documentation` and `--color` via `.rspec`)
58
+ - **HTTP mocking:** WebMock + VCR (optional; loaded if available)
59
+ - **Spec structure** mirrors `lib/` — e.g., `spec/anvil/resources/pdf_spec.rb`
60
+ - Config is reset before each test; `ANVIL_API_KEY` is stubbed to `'test_api_key'`
61
+ - Use `:configured` metadata tag for tests that need `Anvil.configure` called
62
+
63
+ ## Code Style
64
+
65
+ - **RuboCop** with `rubocop-rspec` (see `.rubocop.yml`)
66
+ - Single quotes for strings
67
+ - `frozen_string_literal: true` in every file
68
+ - Max line length: 120
69
+ - Max method length: 25
70
+ - No `Style/Documentation` enforcement
71
+ - Idiomatic Ruby: predicate methods (`complete?`, `draft?`), bang methods (`reload!`, `save_as!`)
72
+
73
+ ## Error Hierarchy
74
+
75
+ ```
76
+ Anvil::Error
77
+ ├── ConfigurationError
78
+ ├── APIError
79
+ │ ├── ValidationError
80
+ │ ├── AuthenticationError
81
+ │ ├── RateLimitError
82
+ │ ├── NotFoundError
83
+ │ └── ServerError
84
+ ├── NetworkError
85
+ │ ├── TimeoutError
86
+ │ └── ConnectionError
87
+ ├── FileError
88
+ │ ├── FileNotFoundError
89
+ │ └── FileTooLargeError
90
+ └── WebhookError
91
+ └── WebhookVerificationError
92
+ ```
93
+
94
+ ## Environment Variables
95
+
96
+ | Variable | Purpose |
97
+ |---|---|
98
+ | `ANVIL_API_KEY` | API key for Anvil |
99
+ | `ANVIL_WEBHOOK_TOKEN` | Token for webhook verification |
100
+ | `ANVIL_TEMPLATE_ID` | Template EID for testing |
101
+ | `ANVIL_ENV` | Environment override (`development` / `production`) |
102
+ | `ANVIL_RSA_PRIVATE_KEY_PATH` | RSA key for webhook decryption |
103
+
104
+ ## CI/CD
105
+
106
+ - **GitHub Actions** — CI pipeline in `.github/workflows/ci.yml` (tests, lint, security)
107
+ - **Gem publishing** — `.github/workflows/gem-push.yml` (triggered by version tags like `v0.2.0`)
108
+ - **Dependabot** — weekly dependency updates
109
+
110
+ ## Releasing
111
+
112
+ 1. Update `lib/anvil/version.rb`
113
+ 2. Update `CHANGELOG.md`
114
+ 3. Commit and tag: `git tag v0.x.x`
115
+ 4. Push: `git push origin main --tags`
116
+
117
+ ## Conventions
118
+
119
+ - Zero runtime dependencies — use only Ruby stdlib
120
+ - Rails-friendly but framework-agnostic
121
+ - Semantic versioning; all new features are additive (no breaking changes)
122
+ - Document new features in CHANGELOG.md and API_COVERAGE.md
123
+ - Write RSpec tests for all new functionality
data/API_COVERAGE.md ADDED
@@ -0,0 +1,294 @@
1
+ # Anvil API Coverage Documentation
2
+
3
+ ## Overview
4
+ This document tracks the implementation status of Anvil API features in the anvil-ruby gem.
5
+
6
+ **Current Coverage: ~30%** of Anvil's API surface
7
+
8
+ ## Implementation Status
9
+
10
+ ### ✅ Implemented Features
11
+
12
+ #### PDF Operations
13
+ - [x] `PDF.fill` - Fill PDF templates with JSON data
14
+ - [x] `PDF.generate` - Generate PDFs from HTML/CSS or Markdown
15
+ - [x] `PDF.save_as` - Save PDF to file
16
+ - [x] `PDF.to_base64` - Convert to base64 encoding
17
+
18
+ #### E-Signatures (Basic)
19
+ - [x] `Signature.create` - Create signature packets
20
+ - [x] `Signature.find` - Find packet by ID
21
+ - [x] `Signature.list` - List signature packets
22
+ - [x] `signing_url` - Generate signing URLs for signers
23
+ - [x] Draft mode support
24
+
25
+ #### Webhooks
26
+ - [x] `Webhook.new` - Parse webhook payloads
27
+ - [x] `Webhook.valid?` - Verify webhook authenticity
28
+ - [x] Token validation with constant-time comparison
29
+ - [x] Basic webhook action detection
30
+
31
+ #### Core Infrastructure
32
+ - [x] API key configuration (multiple methods)
33
+ - [x] Environment management (development/production)
34
+ - [x] Rate limiting with exponential backoff
35
+ - [x] Error handling with specific exception types
36
+ - [x] .env file support
37
+
38
+ ### ❌ Missing Features
39
+
40
+ #### 1. Workflows API (Priority: HIGH)
41
+ **Purpose:** Automate document workflows combining forms, PDFs, and signatures
42
+
43
+ Missing endpoints:
44
+ - [ ] `createWeld` - Create workflow
45
+ - [ ] `updateWeld` - Update workflow configuration
46
+ - [ ] `duplicateWeld` - Clone workflow
47
+ - [ ] `publishWeld` - Publish workflow
48
+ - [ ] `mergeWelds` - Merge multiple workflows
49
+ - [ ] `weld` query - Get workflow details
50
+ - [ ] `weldData` query - Get workflow submission data
51
+
52
+ Proposed Ruby interface:
53
+ ```ruby
54
+ Anvil::Workflow.create(name:, forges:, casts:)
55
+ Anvil::Workflow.find(id)
56
+ Anvil::Workflow.start(workflow_id, data: {})
57
+ Anvil::Workflow.submissions(workflow_id)
58
+ ```
59
+
60
+ #### 2. Webforms/Forge API (Priority: HIGH)
61
+ **Purpose:** Create and manage data collection forms
62
+
63
+ Missing endpoints:
64
+ - [ ] `createForge` - Create webform
65
+ - [ ] `updateForge` - Update webform
66
+ - [ ] `forge` query - Get form configuration
67
+ - [ ] `createSubmission` - Submit form data
68
+ - [ ] `updateSubmission` - Update submission
69
+ - [ ] `submission` query - Get submission data
70
+
71
+ Proposed Ruby interface:
72
+ ```ruby
73
+ Anvil::Webform.create(name:, fields:)
74
+ Anvil::Webform.find(id)
75
+ Anvil::Webform.submit(form_id, data:)
76
+ Anvil::Webform.submissions(form_id)
77
+ ```
78
+
79
+ #### 3. Document AI / OCR (Priority: MEDIUM)
80
+ **Purpose:** Extract data from documents using AI/OCR
81
+
82
+ Missing capabilities:
83
+ - [ ] Text extraction from PDFs
84
+ - [ ] Field detection and labeling
85
+ - [ ] Document classification
86
+ - [ ] Structured data extraction
87
+
88
+ Proposed Ruby interface:
89
+ ```ruby
90
+ Anvil::DocumentAI.extract_text(file:)
91
+ Anvil::DocumentAI.identify_fields(file:)
92
+ Anvil::DocumentAI.extract_data(file:, schema:)
93
+ ```
94
+
95
+ #### 4. Cast (PDF Template) Management (Priority: MEDIUM)
96
+ **Purpose:** Programmatically manage PDF templates
97
+
98
+ Missing endpoints:
99
+ - [ ] `createCast` - Create template
100
+ - [ ] `updateCast` - Update template
101
+ - [ ] `duplicateCast` - Clone template
102
+ - [ ] `publishCast` - Publish template
103
+ - [ ] `cast` query - Get template details
104
+
105
+ Proposed Ruby interface:
106
+ ```ruby
107
+ Anvil::Cast.create(file:, fields:)
108
+ Anvil::Cast.update(id, fields:)
109
+ Anvil::Cast.duplicate(id)
110
+ Anvil::Cast.list
111
+ ```
112
+
113
+ #### 5. Advanced E-Signature Features (Priority: HIGH)
114
+ **Purpose:** Complete signature packet management
115
+
116
+ Missing endpoints:
117
+ - [ ] `updateEtchPacket` - Update packet
118
+ - [ ] `sendEtchPacket` - Send packet (from draft)
119
+ - [ ] `removeEtchPacket` - Delete packet
120
+ - [ ] `skipSigner` - Skip a signer
121
+ - [ ] `notifySigner` - Send reminder
122
+ - [ ] `updateEtchTemplate` - Update template
123
+ - [ ] `voidDocumentGroup` - Void signed documents
124
+ - [ ] `expireSignerTokens` - Expire signing sessions
125
+
126
+ Proposed Ruby interface:
127
+ ```ruby
128
+ packet.update(name:, signers:)
129
+ packet.send!
130
+ packet.delete!
131
+ packet.skip_signer(signer_id)
132
+ packet.notify_signer(signer_id)
133
+ packet.void!
134
+ ```
135
+
136
+ #### 6. Organization Management (Priority: LOW)
137
+ **Purpose:** Manage organization settings and users
138
+
139
+ Missing endpoints:
140
+ - [ ] `organization` query - Get org details
141
+ - [ ] `updateOrganization` - Update settings
142
+ - [ ] `updateOrganizationUser` - Manage users
143
+ - [ ] `currentUser` query - Get current user
144
+
145
+ Proposed Ruby interface:
146
+ ```ruby
147
+ Anvil::Organization.get
148
+ Anvil::Organization.update(settings:)
149
+ Anvil::Organization.users
150
+ Anvil::Organization.add_user(email:, role:)
151
+ ```
152
+
153
+ #### 7. Embedded Builders (Priority: LOW)
154
+ **Purpose:** Embed Anvil UI builders in your application
155
+
156
+ Missing endpoints:
157
+ - [ ] `generateEmbedURL` - Create embed session
158
+ - [ ] Session management
159
+
160
+ Proposed Ruby interface:
161
+ ```ruby
162
+ Anvil::EmbeddedBuilder.generate_url(type:, options:)
163
+ Anvil::EmbeddedBuilder.create_session
164
+ ```
165
+
166
+ #### 8. Webhook Management (Priority: MEDIUM)
167
+ **Purpose:** Programmatically manage webhooks
168
+
169
+ Missing endpoints:
170
+ - [ ] `createWebhook` - Create webhook
171
+ - [ ] `updateWebhook` - Update webhook
172
+ - [ ] `removeWebhook` - Delete webhook
173
+ - [ ] `createWebhookAction` - Create webhook action
174
+ - [ ] `removeWebhookAction` - Remove action
175
+ - [ ] `webhookLog` query - Get webhook logs
176
+ - [ ] `retryWebhookLog` - Retry failed webhook
177
+
178
+ Proposed Ruby interface:
179
+ ```ruby
180
+ Anvil::Webhook.create(url:, events:)
181
+ Anvil::Webhook.update(id, url:)
182
+ Anvil::Webhook.delete(id)
183
+ Anvil::WebhookLog.list
184
+ Anvil::WebhookLog.retry(id)
185
+ ```
186
+
187
+ #### 9. Generic GraphQL Support (Priority: HIGH)
188
+ **Purpose:** Allow custom GraphQL queries/mutations
189
+
190
+ Proposed Ruby interface:
191
+ ```ruby
192
+ Anvil::Client.query(graphql_string, variables: {})
193
+ Anvil::Client.mutation(graphql_string, variables: {})
194
+ ```
195
+
196
+ ## GraphQL Operations Summary
197
+
198
+ ### Available Queries (9 total)
199
+ - `cast` - PDF template details
200
+ - `currentUser` - User info
201
+ - `etchPacket` - Signature packet
202
+ - `forge` - Webform config
203
+ - `organization` - Org details
204
+ - `signer` - Signer info
205
+ - `submission` - Form submission
206
+ - `webhookLog` - Webhook history
207
+ - `weld` - Workflow config
208
+ - `weldData` - Workflow data
209
+
210
+ ### Available Mutations (35 total)
211
+
212
+ **Document Operations (11):**
213
+ - createCast, updateCast, duplicateCast, publishCast
214
+ - createWeld, updateWeld, duplicateWeld, publishWeld, mergeWelds
215
+ - createForge, updateForge
216
+
217
+ **E-Signature (6):**
218
+ - createEtchPacket, updateEtchPacket, sendEtchPacket
219
+ - removeEtchPacket, generateEtchSignURL, updateEtchTemplate
220
+
221
+ **Workflow Data (6):**
222
+ - createWeldData, updateWeldData, removeWeldData
223
+ - createSubmission, updateSubmission, destroySubmission
224
+
225
+ **Configuration (7):**
226
+ - createWebhook, updateWebhook, removeWebhook
227
+ - createWebhookAction, removeWebhookAction
228
+ - updateOrganization, updateOrganizationUser
229
+
230
+ **Utilities (5):**
231
+ - generateEmbedURL, expireSessionToken, expireSignerTokens
232
+ - notifySigner, skipSigner, retryWebhookLog
233
+ - disconnectDocusign, voidDocumentGroup
234
+
235
+ ## Implementation Phases
236
+
237
+ ### Phase 1: Core Features (v0.2.0)
238
+ 1. Generic GraphQL support
239
+ 2. Complete e-signature features
240
+ 3. Basic workflow support
241
+ 4. Basic webform support
242
+
243
+ ### Phase 2: Advanced Features (v0.3.0)
244
+ 1. Full workflow implementation
245
+ 2. Full webform implementation
246
+ 3. Cast management
247
+ 4. Webhook management
248
+
249
+ ### Phase 3: AI & Enterprise (v0.4.0)
250
+ 1. Document AI/OCR
251
+ 2. Organization management
252
+ 3. Embedded builders
253
+ 4. Advanced utilities
254
+
255
+ ## Testing Requirements
256
+
257
+ Each feature implementation should include:
258
+ 1. Unit tests (RSpec)
259
+ 2. Integration tests (with VCR cassettes)
260
+ 3. Documentation (YARD comments)
261
+ 4. Usage examples
262
+ 5. Error handling tests
263
+
264
+ ## Dependencies
265
+
266
+ Current gem has zero runtime dependencies (except base64 for Ruby 3.4+).
267
+ We should maintain this approach where possible.
268
+
269
+ Optional dependencies to consider:
270
+ - `multipart-post` - For file uploads (already optional)
271
+ - `marcel` - For MIME type detection (if needed)
272
+
273
+ ## Breaking Changes
274
+
275
+ None expected. All new features will be additive.
276
+
277
+ ## Notes for Implementation
278
+
279
+ 1. Maintain consistent API design with existing patterns
280
+ 2. Use resource-based architecture (ActiveResource-like)
281
+ 3. Keep methods idiomatic Ruby (predicates, bang methods)
282
+ 4. Provide both simple and advanced interfaces
283
+ 5. Handle errors consistently with existing error classes
284
+ 6. Support per-request API key overrides for multi-tenancy
285
+
286
+ ## References
287
+
288
+ - [Anvil API Documentation](https://www.useanvil.com/docs/)
289
+ - [GraphQL Reference](https://www.useanvil.com/docs/api/graphql/reference/)
290
+ - [GraphQL Schema](https://app.useanvil.com/graphql/sdl) (requires auth)
291
+
292
+ ---
293
+ *Last Updated: January 2024*
294
+ *Current Gem Version: 0.1.0*
data/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2024-01-15
11
+
12
+ ### Added
13
+ - Initial release of the Anvil Ruby gem
14
+ - PDF filling support via `Anvil::PDF.fill`
15
+ - PDF generation from HTML/CSS via `Anvil::PDF.generate_from_html`
16
+ - PDF generation from Markdown via `Anvil::PDF.generate_from_markdown`
17
+ - E-signature packet creation and management via `Anvil::Signature`
18
+ - Webhook verification and handling via `Anvil::Webhook`
19
+ - Flexible API key configuration (Rails initializer, environment variable, direct assignment)
20
+ - Multi-tenant support with per-request API key override
21
+ - Automatic rate limiting with exponential backoff
22
+ - Comprehensive error handling with specific exception types
23
+ - Zero runtime dependencies - uses only Ruby standard library
24
+ - Rails-friendly design while remaining framework agnostic
25
+ - Full RSpec test suite
26
+ - Extensive documentation and examples
27
+
28
+ ### Security
29
+ - Secure webhook token verification with constant-time comparison
30
+ - Support for RSA-encrypted webhook payloads
31
+ - MFA required for RubyGems publishing
32
+
33
+ [Unreleased]: https://github.com/nickMarz/Ruby-Anvil/compare/v0.1.0...HEAD
34
+ [0.1.0]: https://github.com/nickMarz/Ruby-Anvil/releases/tag/v0.1.0
data/CLAUDE_README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Instructions for Claude
2
+
3
+ ## 🚀 Quick Start for New Sessions
4
+
5
+ When starting a new session with this project, please:
6
+
7
+ 1. **Read the project notes**:
8
+ ```
9
+ Read .claude-project-notes.md
10
+ ```
11
+
12
+ 2. **Check current status**:
13
+ ```bash
14
+ git status
15
+ git log -1
16
+ ```
17
+
18
+ 3. **Understand the project**:
19
+ - This is the Anvil Ruby gem for document automation
20
+ - GitHub Actions are fully configured for CI/CD
21
+ - Tests should always pass before committing
22
+
23
+ ## 📝 Important Context
24
+
25
+ ### GitHub Actions Setup (Completed Jan 15, 2024)
26
+ - ✅ CI pipeline (`.github/workflows/ci.yml`)
27
+ - ✅ Gem publishing (`.github/workflows/gem-push.yml`)
28
+ - ✅ Dependabot configuration
29
+ - ✅ Full documentation in `.github/workflows/README.md`
30
+
31
+ ### Required Secrets
32
+ - `RUBYGEM_API_KEY` - Must be added to GitHub for gem publishing
33
+ - `ANVIL_API_KEY` - Optional, for running tests
34
+
35
+ ### Project Conventions
36
+ - Use RuboCop for style (`bundle exec rubocop`)
37
+ - Write tests for all new features (`bundle exec rspec`)
38
+ - Zero runtime dependencies (except base64 for Ruby 3.4+)
39
+ - Follow semantic versioning
40
+
41
+ ## 🎯 Common Tasks
42
+
43
+ ### Before ANY commit:
44
+ ```bash
45
+ bundle exec rubocop
46
+ bundle exec rspec
47
+ ```
48
+
49
+ ### To release a new version:
50
+ 1. Update `lib/anvil/version.rb`
51
+ 2. Update `CHANGELOG.md`
52
+ 3. Commit and tag: `git tag v0.x.x`
53
+ 4. Push: `git push origin main --tags`
54
+
55
+ ### To run CI locally:
56
+ ```bash
57
+ bundle exec rubocop # Linting
58
+ bundle exec rspec # Tests
59
+ bundle-audit check --update # Security
60
+ gem build *.gemspec # Build
61
+ ```
62
+
63
+ ## 🔧 Development Workflow
64
+
65
+ 1. **Always use TodoWrite tool** for multi-step tasks
66
+ 2. **Run tests** before committing changes
67
+ 3. **Check CI status** after pushing
68
+ 4. **Document** any new features or changes
69
+
70
+ ## 👤 User Preferences (Nick Marazzo)
71
+
72
+ - Prefers practical, working solutions
73
+ - Values comprehensive documentation
74
+ - Likes Ruby best practices and idiomatic code
75
+ - Appreciates proactive error handling
76
+ - Wants CI/CD automation for everything
77
+
78
+ ## 📁 Key Files
79
+
80
+ - `.github/workflows/` - GitHub Actions workflows
81
+ - `lib/anvil/` - Main gem code
82
+ - `spec/` - Test files
83
+ - `examples/` - Usage examples
84
+ - `.rubocop.yml` - Style configuration
85
+ - `anvil-ruby.gemspec` - Gem specification
86
+
87
+ ## 🚨 Important Reminders
88
+
89
+ 1. **Never** commit without running tests
90
+ 2. **Always** update CHANGELOG.md for new features
91
+ 3. **Check** GitHub Actions after pushing
92
+ 4. **Update** documentation for API changes
93
+ 5. **Test** against multiple Ruby versions locally if possible
94
+
95
+ ---
96
+
97
+ *This file helps Claude understand the project context in new sessions.*
98
+ *Last updated: January 15, 2024*