Skip to content

v4.13.0: New resources, external-id operations, and disable toggles#184

Open
jessicahearn wants to merge 17 commits intomainfrom
jessica/pip-309-ruby-sdk-feature-updates
Open

v4.13.0: New resources, external-id operations, and disable toggles#184
jessicahearn wants to merge 17 commits intomainfrom
jessica/pip-309-ruby-sdk-feature-updates

Conversation

@jessicahearn
Copy link
Copy Markdown
Contributor

@jessicahearn jessicahearn commented Feb 13, 2026

Summary

  • Add standalone Transaction and LineItem resources with CRUD, toggle_disabled!, and external-id operations
  • Add JsonImport resource for bulk JSON imports (create + retrieve)
  • Add Upload resource for CSV file uploads via multipart (requires faraday-multipart)
  • Add Invoice toggle_disabled!, update_status!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!
  • Add SubscriptionEvent toggle_disabled!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!
  • Add SubscriptionEvent class-level destroy! accepting both flat and envelope-wrapped params for backwards compatibility
  • Add Account include parameter support and id readonly attribute
  • Add errors readonly attribute to LineItem and Transaction (PIP-304)
  • Add handle_as_user_edit query parameter to all write methods
  • URL-encode user-supplied query parameters in API request paths
  • Add missing middleware (RaiseError, retry, User-Agent) to Upload multipart connection
  • Extract shared Concerns::ToggleDisabled and Concerns::ExternalIdOperations to reduce duplication
  • Add build_query_path, json_patch, json_post helpers to APIResource
  • Remove outdated post-install gem message
  • Bump version to 4.13.0

Backwards compatibility review

All changes are additive — no existing method signatures, return types, or behaviors were altered. Safe as a minor (4.13.0) release.

Modified resources

Resource Change Compat
Account.retrieve Signature changed from () to (include: nil) Safeinclude defaults to nil, existing calls work identically
Invoice Added Update action, ToggleDisabled, ExternalIdOperations concerns, update_status! Safe — purely additive; existing Retrieve, Destroy, attributes, all, serialize_*, private setters unchanged
SubscriptionEvent Added disabled/disabled_at readonly attrs, class-level destroy!, toggle/external-id methods Safe — new attrs additive; instance destroy! untouched; no class-level destroy! existed on main
APIResource Added require "cgi"/"uri", build_query_path, json_patch, json_post Safe — additive class methods; cgi already available transitively
gemspec Removed post_install_message Safe — only affects install-time banner, not runtime

New resources — no collision

New class Notes
ChartMogul::Transaction Transactions::Payment/Refund exist under a module namespace — no collision
ChartMogul::LineItem LineItems::Subscription/OneTime exist under a module namespace — no collision
ChartMogul::JsonImport Entirely new
ChartMogul::Upload Entirely new
Concerns::ToggleDisabled New shared concern
Concerns::ExternalIdOperations New shared concern

Note

SubscriptionEvent.destroy! — new class method alongside existing instance method. Ruby class and instance methods don't collide. Users calling event.destroy! on an instance still get the original instance method with no behavior change.

Automated test plan

  • All 349 RSpec tests pass (98.49% line coverage)
  • Unit tests for all new resources and methods
  • Tests for handle_as_user_edit query parameter across all resources
  • Tests for SubscriptionEvent destroy backwards compatibility (flat + envelope params)

Testing instructions

Use ChartMogul account WiktorOnboarding (acc_d0ea225e-f0f1-40ab-92cf-659dce5f2b76). Impersonate user wiktor.plaga@chartmogul.com to find the API key in the account settings. The test script creates its own data source, customer, plan, invoice (with line items and transactions), and subscription events — then cleans everything up on exit. Toggle tests use the existing Stripe data source (ds_bdb16dbc-...) since toggle_disabled is not allowed on Custom data sources.

Quick run (tests all features end-to-end):

cd sdks/rb && gem build chartmogul-ruby.gemspec
cd sdks/tests/rb && bundle install
CHARTMOGUL_API_KEY='<key>' bundle exec ruby test_pip_310.rb

Result: 31 tests — 29 pass, 2 known flaky (SE external_id indexing on fresh Custom DS takes minutes; SDK code verified correct via Stripe SE tests).

Account include parameter

# Without include — optional fields are nil
account = ChartMogul::Account.retrieve
account.id                   # => "acc_d0ea225e-..."
account.churn_recognition    # => nil

# With include — requested fields are populated
account = ChartMogul::Account.retrieve(include: %w[churn_recognition refund_handling])
account.churn_recognition    # => "churn_at_time_of_cancelation"
account.refund_handling      # => { ... }

Invoice operations

# toggle_disabled! (requires handle_as_user_edit on Stripe DS)
inv = ChartMogul::Invoice.retrieve('inv_...')
inv.toggle_disabled!(disabled: true, handle_as_user_edit: true)
inv.disabled  # => true
inv.toggle_disabled!(disabled: false, handle_as_user_edit: true)

# update_status!
ChartMogul::Invoice.update_status!(
  data_source_uuid: 'ds_...', invoice_external_id: 'ext_123', status: 'voided'
)  # => true

# update_by_external_id!
inv = ChartMogul::Invoice.update_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'ext_123', due_date: '2026-03-15T00:00:00Z'
)

# toggle_disabled_by_external_id!
ChartMogul::Invoice.toggle_disabled_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'ext_123', disabled: true, handle_as_user_edit: true
)

# destroy_by_external_id!
ChartMogul::Invoice.destroy_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'ext_123'
)  # => true

Standalone LineItem resource

# Create on an invoice
li = ChartMogul::LineItem.create!(
  invoice_uuid: 'inv_...', type: 'one_time', amount_in_cents: 2500,
  description: 'Test item', external_id: 'li_test_1'
)

# Retrieve by UUID and by external_id
li = ChartMogul::LineItem.retrieve('li_...')
li = ChartMogul::LineItem.retrieve_by_external_id(data_source_uuid: 'ds_...', external_id: 'li_test_1')

# Toggle disabled (instance)
li.toggle_disabled!(disabled: true, handle_as_user_edit: true)

# Update, toggle, destroy by external_id (class methods)
ChartMogul::LineItem.update_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'li_test_1', description: 'Updated'
)
ChartMogul::LineItem.toggle_disabled_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'li_test_1', disabled: true, handle_as_user_edit: true
)
ChartMogul::LineItem.destroy_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'li_test_1'
)  # => true

Standalone Transaction resource

# Retrieve by UUID and by external_id
txn = ChartMogul::Transaction.retrieve('tr_...')
txn = ChartMogul::Transaction.retrieve_by_external_id(data_source_uuid: 'ds_...', external_id: 'txn_1')

# Toggle disabled (instance)
txn.toggle_disabled!(disabled: true, handle_as_user_edit: true)

# Update, toggle, destroy by external_id (class methods)
ChartMogul::Transaction.update_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'txn_1', result: 'failed'
)
ChartMogul::Transaction.toggle_disabled_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'txn_1', disabled: true, handle_as_user_edit: true
)
ChartMogul::Transaction.destroy_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'txn_1'
)  # => true

SubscriptionEvent operations

# Create
se = ChartMogul::SubscriptionEvent.create!(
  data_source_uuid: 'ds_...', customer_external_id: 'cust_1',
  subscription_external_id: 'sub_1', plan_external_id: 'plan_1',
  event_date: '2026-01-15T00:00:00Z', effective_date: '2026-01-15T00:00:00Z',
  event_type: 'subscription_start_scheduled', external_id: 'se_1',
  quantity: 1, currency: 'USD', amount_in_cents: 10_000
)

# Toggle disabled (instance — uses Stripe SE for testing)
event.toggle_disabled!(disabled: true, handle_as_user_edit: true)

# Update by external_id
ChartMogul::SubscriptionEvent.update_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'se_1', quantity: 5
)

# Toggle disabled by external_id
ChartMogul::SubscriptionEvent.toggle_disabled_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'se_1', disabled: true, handle_as_user_edit: true
)

# Destroy — flat params (new) and envelope-wrapped (backwards compat)
ChartMogul::SubscriptionEvent.destroy!(id: se.id)
ChartMogul::SubscriptionEvent.destroy!(subscription_event: { id: se.id })

# Destroy by external_id
ChartMogul::SubscriptionEvent.destroy_by_external_id!(
  data_source_uuid: 'ds_...', external_id: 'se_1'
)  # => true

JsonImport resource

import = ChartMogul::JsonImport.create!(
  data_source_uuid: 'ds_...',
  customers: [{ external_id: 'cust_1', name: 'Test', email: 'test@example.com' }]
)
import.id      # => "ji_..."
import.status  # => "queued"

# Retrieve status
status = ChartMogul::JsonImport.retrieve(data_source_uuid: 'ds_...', id: import.id)
status.status  # => "completed"

handle_as_user_edit parameter

All write methods across Invoice, LineItem, Transaction, and SubscriptionEvent accept handle_as_user_edit: as a keyword argument. It is appended as a URL query parameter (?handle_as_user_edit=true). Tested in LineItem.create!, LineItem.update_by_external_id!, and all toggle_disabled! variants.


🤖 Generated with Claude Code

@jessicahearn jessicahearn self-assigned this Feb 13, 2026
jessicahearn and others added 6 commits March 17, 2026 12:17
- Add Account `include` parameter for optional settings (churn_recognition,
  churn_when_zero_mrr, auto_churn_subscription, refund_handling,
  proximate_movement_reclassification)
- Add DataSource `empty!` and `soft_purge!` methods for data management
- Add Invoice `update!`, `toggle_disabled!`, `update_status!` methods
- Add SubscriptionEvent `toggle_disabled!` method
- Add standalone Transaction resource with CRUD and `toggle_disabled!`
- Add standalone LineItem resource with CRUD and `toggle_disabled!`
- Add external ID lookup methods (`*_by_external_id`) for Invoice,
  Transaction, LineItem, and SubscriptionEvent
- Add JsonImport resource for bulk JSON imports
- Add Upload resource for CSV file uploads (requires faraday-multipart)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added optional handle_as_user_edit parameter to:
- Invoice: toggle_disabled!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!
- Transaction: toggle_disabled!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!
- LineItem: create!, toggle_disabled!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!
- SubscriptionEvent: toggle_disabled!, update_by_external_id!, destroy_by_external_id!, toggle_disabled_by_external_id!

This allows API consumers to indicate when changes should be treated as user edits for edit history tracking purposes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a class-level destroy! method that accepts both flat params and
envelope-wrapped params for full backwards compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wscourge wscourge force-pushed the jessica/pip-309-ruby-sdk-feature-updates branch from 1414f52 to 1bb31e2 Compare March 17, 2026 11:19
wscourge and others added 6 commits March 17, 2026 17:04
Tests cover new_from_json (including errors/edit_history_summary fields),
CRUD operations, toggle_disabled, by_external_id methods, and
handle_as_user_edit query parameter support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…_id methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…thods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wscourge
Copy link
Copy Markdown
Contributor

@claude review

@wscourge wscourge marked this pull request as ready for review March 17, 2026 16:15
@wscourge
Copy link
Copy Markdown
Contributor

@claude review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the ChartMogul Ruby SDK with new v4.13.0 resources and convenience endpoints (uploads/imports, external-id lookups, disable toggles), and bumps the gem version + changelog accordingly.

Changes:

  • Add new resources: Transaction, LineItem, JsonImport, and Upload (CSV multipart).
  • Add new operations to existing resources: Account include, DataSource empty! / soft_purge!, Invoice toggle/update-by-external-id/status, SubscriptionEvent disable toggle + external-id ops.
  • Add/extend specs for the newly added endpoints and behaviors, and update version/changelog.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
spec/chartmogul/upload_spec.rb Adds tests for CSV upload creation (multipart) and attribute parsing
spec/chartmogul/transaction_spec.rb Adds tests for Transaction external-id operations and disable toggling
spec/chartmogul/subscription_event_spec.rb Adds tests for SubscriptionEvent destroy variants, disable toggling, and external-id operations
spec/chartmogul/line_item_spec.rb Adds tests for LineItem CRUD-like endpoints + external-id ops + disable toggling
spec/chartmogul/json_import_spec.rb Adds tests for JsonImport create/retrieve endpoints
spec/chartmogul/invoice_spec.rb Adds tests for new Invoice disable toggling + external-id ops + status update
spec/chartmogul/data_source_spec.rb Adds tests for DataSource empty! and soft_purge!
spec/chartmogul/account_spec.rb Adds tests for Account .retrieve(include: ...) behavior
lib/chartmogul/version.rb Bumps gem version to 4.13.0
lib/chartmogul/upload.rb Implements Upload resource + multipart CSV upload
lib/chartmogul/transaction.rb Implements standalone Transaction resource + external-id ops + disable toggles
lib/chartmogul/subscription_event.rb Adds disabled fields, toggle APIs, and external-id update/destroy/toggle methods
lib/chartmogul/line_item.rb Implements standalone LineItem resource + external-id ops + disable toggles
lib/chartmogul/json_import.rb Implements JsonImport create/retrieve for bulk JSON import
lib/chartmogul/invoice.rb Adds Invoice update support + disable toggles + external-id ops + status update
lib/chartmogul/data_source.rb Adds DataSource empty! and soft_purge! methods
lib/chartmogul/account.rb Adds include parameter support and optional account settings attributes
lib/chartmogul.rb Requires the newly added resource files
chartmogul-ruby.gemspec Removes the post-install message
changelog.md Adds 4.13.0 changelog entry describing new SDK features

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

wscourge and others added 2 commits March 18, 2026 11:26
Wraps external_id, data_source_uuid, invoice_external_id, include
fields, and switch_system values with CGI.escape to prevent malformed
URLs when values contain reserved characters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds RaiseError, retry, and User-Agent middleware to match the standard
APIResource connection, ensuring consistent error handling and retries
for multipart upload requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wscourge wscourge changed the title Add SDK features for v4.12.0 Ruby SDK v4.13.0: Add new resources, endpoints, and convenience methods Mar 18, 2026
@wscourge wscourge changed the title Ruby SDK v4.13.0: Add new resources, endpoints, and convenience methods Ruby SDK v4.13.0: New resources, external-id operations, and disable toggles Mar 18, 2026
@wscourge wscourge changed the title Ruby SDK v4.13.0: New resources, external-id operations, and disable toggles v4.13.0: New resources, external-id operations, and disable toggles Mar 20, 2026
wscourge and others added 3 commits March 24, 2026 13:26
- Add Concerns::ToggleDisabled and Concerns::ExternalIdOperations to
  eliminate ~150 lines of duplicated code across LineItem, Transaction,
  and Invoice resources
- Add build_query_path, json_patch, json_post helpers to APIResource
  for proper URL encoding and DRY JSON request handling
- Memoize Upload multipart_connection to avoid rebuilding per call
- Document SubscriptionEvent envelope-wrapping pattern

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants