Skip to content

feat(billing): add invoice_item_types to LineItemDetails#295

Open
dashed wants to merge 2 commits into
mainfrom
aleal/feat/lineitem-invoice-item-types
Open

feat(billing): add invoice_item_types to LineItemDetails#295
dashed wants to merge 2 commits into
mainfrom
aleal/feat/lineitem-invoice-item-types

Conversation

@dashed

@dashed dashed commented Jun 5, 2026

Copy link
Copy Markdown
Member

This is for https://github.com/getsentry/getsentry/pull/20573

What

Adds a nested InvoiceItemTypes message to line_item_details.proto and attaches it to LineItemDetails as invoice_item_types (field number 2, previously unused).

message LineItemDetails {
  string uid = 1;
  InvoiceItemTypes invoice_item_types = 2;  // new
  string customer_facing_name = 3;
  string plural = 4;
  UnitInfo units = 5;
  BillableMetric billable_metric = 6;
}

message InvoiceItemTypes {
  optional string reserved  = 1;
  optional string ondemand  = 2;
  optional string activated = 3;
}

Why

A single SKU's reserved, on-demand, and activated usage can each settle as a distinct InvoiceItemType. Collocating those identifiers on the SKU's LineItemDetails lets getsentry declare them per SKU, instead of growing a shared enum every time a new SKU/context combination appears.

Each context is optional because not every SKU uses every context — some SKUs (e.g. Seer) fold their usage irregularly and only populate a subset.

Bindings

  • Rust bindings regenerated (make build-rust) — the tracked .rs now contains InvoiceItemTypes and LineItemDetails.invoice_item_types.
  • Python bindings regenerated (make build-py); the py/ output is gitignored and not part of this diff.
  • Cargo.lock left at main's version (the build's version-bump drift was reverted).

Compatibility

Purely additive — a new message and a new field on a previously-unused field number. No existing fields change.

A SKU's reserved, on-demand, and activated usage can each settle as a
distinct InvoiceItemType. Collocating those identifiers on the SKU's
LineItemDetails lets getsentry declare them per SKU instead of growing a
shared enum. The new InvoiceItemTypes message keeps each context optional
because some SKUs (e.g. Seer) fold their usage irregularly and do not
populate every context.
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow ci / buf-checks (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJun 5, 2026, 9:59 PM

@dashed dashed self-assigned this Jun 5, 2026
@dashed dashed marked this pull request as ready for review June 5, 2026 22:43
@dashed dashed requested a review from a team as a code owner June 5, 2026 22:43
Comment thread proto/sentry_protos/billing/v1/common/v1/line_item_details.proto
optional string reserved = 1;

// Type for on-demand (pay-as-you-go) usage of this SKU.
optional string ondemand = 2;

@volokluev volokluev Jun 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

according to the changelog, ondemand has been replaced with payg, can we keep this consistent?

Comment on lines +41 to +42
// Type for activated usage of this SKU.
optional string activated = 3;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what is "activated usage"? what are the example values for it?

BillableMetric billable_metric = 6;
}

// InvoiceItemType identifiers for a single SKU, split by billing context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what is a SKU? Have we defined it somewhere?

// distinct InvoiceItemType, so every context carries its own identifier instead
// of collapsing into one. Contexts are optional because some SKUs (e.g. Seer)
// fold their usage irregularly and do not populate every context.
message InvoiceItemTypes {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it's not clear to me why we would need to expose this in the proto as anything but an enum. We already have the billable_metric, the customer_facing_name, why would we also need to add reserved_errors, reserved_trace_metric_bytes etc to the list? Why not just an enum of

enum InvoiceItemType {
    INVOICE_ITEM_TYPE_RESERVED = 1;
    INVOICE_ITEM_TYPE_PAYG = 2;
    INVOICE_ITEM_TYPE_ACTIVATED = 2;
}

I don't see why downstream services which need to generate a string like reserved_errors for their own purposes need that to be exposed in the lineitem proto

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.

2 participants