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 +7 -0
- data/AGENTS.md +123 -0
- data/API_COVERAGE.md +294 -0
- data/CHANGELOG.md +34 -0
- data/CLAUDE_README.md +98 -0
- data/GITHUB_ACTIONS_QUICKREF.md +174 -0
- data/Gemfile.lock +112 -0
- data/Gemfile.minimal +9 -0
- data/LICENSE +21 -0
- data/PROJECT_CONTEXT.md +196 -0
- data/README.md +445 -0
- data/anvil-ruby.gemspec +66 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/create_signature_direct.rb +142 -0
- data/create_signature_packet.rb +232 -0
- data/debug_env.rb +28 -0
- data/examples/create_signature.rb +194 -0
- data/examples/fill_pdf.rb +89 -0
- data/examples/generate_pdf.rb +347 -0
- data/examples/verify_webhook.rb +281 -0
- data/lib/anvil/client.rb +216 -0
- data/lib/anvil/configuration.rb +87 -0
- data/lib/anvil/env_loader.rb +30 -0
- data/lib/anvil/errors.rb +95 -0
- data/lib/anvil/rate_limiter.rb +66 -0
- data/lib/anvil/resources/base.rb +100 -0
- data/lib/anvil/resources/pdf.rb +171 -0
- data/lib/anvil/resources/signature.rb +517 -0
- data/lib/anvil/resources/webform.rb +154 -0
- data/lib/anvil/resources/webhook.rb +201 -0
- data/lib/anvil/resources/workflow.rb +169 -0
- data/lib/anvil/response.rb +98 -0
- data/lib/anvil/version.rb +5 -0
- data/lib/anvil.rb +88 -0
- data/quickstart_signature.rb +220 -0
- data/test_api_connection.rb +143 -0
- data/test_etch_signature.rb +230 -0
- data/test_gem.rb +72 -0
- data/test_signature.rb +281 -0
- data/test_signature_with_template.rb +112 -0
- metadata +247 -0
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*
|