Skip to content

feat(billing-platform): package service protos#201

Merged
volokluev merged 14 commits intomainfrom
volo/package_protos
Apr 20, 2026
Merged

feat(billing-platform): package service protos#201
volokluev merged 14 commits intomainfrom
volo/package_protos

Conversation

@volokluev
Copy link
Copy Markdown
Member

This PR creates a package service directory and extracts the PricingConfig out of the V1 contract service and puts it onto the package service.

In doing so, I'm pulling out things which are going to be used across services such as:

  • Tier definitions
  • billable metrics
  • LineItems

I am also moving AWAY from defining SKUs in protos and away from the name SKU in general. It has too many connotations, nobody knows what it means. The word we are using to express the thing that will be billed for (and show up as a line item on an invoice) is LineItem

I am making the package service be the source of truth for:

  • What to call a line item
  • how a line item is derived from usage data

we should not need to define the line item in our protos

volokluev and others added 4 commits April 17, 2026 14:58
…ervice

Consolidate billing protos by moving common items (line_item_details, unit_info) from v2/common to v1/common and add new package service definitions. Update package declarations and import paths to reflect new v1 location.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Move PricingTier and TieredPricingRate message definitions from package service to common/v1 directory for reusability across services.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 17, 2026

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

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedApr 20, 2026, 10:40 PM

Comment on lines +15 to +18
oneof reserved_units {
bool is_unlimited = 5;
uint64 num_reserved_units = 6; // the type communicates whether the line item is unlimited or not, additionally reserved budget line items have a non-zero reserved_rate in addition to 0 reserved_units
}
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.

shouldn't this live in the Contract? or will each contract also create a Package?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good call, I think I should change the naming. This should be more like inlcuded_reserved_units

Comment thread proto/sentry_protos/billing/v1/common/v1/billable_metric.proto
Comment thread proto/sentry_protos/billing/v1/common/v1/line_item_details.proto Outdated
string full_name = 2;

// Base unit for conversion (e.g., "byte", "meter", "count").
string base_unit = 3;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we make this an enum?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

good call

repeated LineItemConfig line_item_configs = 2;
repeated SharedLineItemBudget shared_line_item_budgets = 3;
// Base price for the package.
uint64 base_price_cents = 4;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we turn base price into a line item? I think it should be representable as an Expression. We might have additional kinds of constant non-usage based pricing in the future that would be nice to model all in the same way

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

On the one hand it makes sense, you define a line item and then it directly becomes an invoice line item, on the other hand, there is a relationship here that I don't think makes sense to discard.

this may be the problem with calling things LineItem(s) instead of SKUs or Products. Because we use this word, we expect that what we define in a package will map 1:1 with an invoice line item (which afaics is a presentation concern), rather than a category of invoice line items. For example: an invoice will have:

  metrics (base price): $10
  metrics (reserved_spend): $30
  metrics (payg spend): $20

Presented on an invoice, they may all be different lines, but they are part of the same category of line items with a pricing configuration that is defined as one.

In the package service, I'm not actually describing the line items separately, I describing a product and what its rates are (in this case metrics).

If I think about driving the checkout page, it makes sense to bundle together the related costs of metrics (base price, included reserved units, reservation costs, and payg costs).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think I also may have mis-perceived what you were commenting on. You meant to make the package base price into a lineitem. Let me consider that a bit more. My initial reaction is I'm not opposed to it, and it's also probably not hard to change later

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

oh yeah I meant the package base price 👍 (like $29)

volokluev and others added 2 commits April 20, 2026 11:27
Add test demonstrating how to create a BillableMetric with a complex
expression that combines two data categories using binary operations.
Shows the pattern: profile_indexed * 0.3 + transaction_indexed

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Comment thread proto/sentry_protos/billing/v1/common/v1/billable_metric.proto
Comment thread py/tests/test_billing_v1.py Outdated
Remove assertions from test as it's only meant to illustrate how
the protos work together, not verify implementation details.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
repeated sentry_protos.billing.v1.common.v1.LineItemDetails line_items = 3;
}

message PackageConfig {
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.

we'll want a field to specify annual vs monthly packages

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I envisioned that being on the contract not the package, but thinking about it more I guess the billing cadence determines what the actual price is so maybe it has to be on the package

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I have added it, good spot

volokluev and others added 4 commits April 20, 2026 13:19
- Add proper oneof name (category_type) to CategoryReference
- Rename fields to data_category and seat_category to avoid conflicts
- Add BaseUnit enum to unit_info.proto
- Update tests to use new field names
- Fix Rust test to include date field in GetContractRequest
- Regenerate Rust bindings

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

message LineItemConfig {
// Base price for the line item (upgraded reserved volumes or add-on activation fees)
uint64 base_price_cents = 1;
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.

so would we have a LineItemConfig for each reserved tier? ie 50k errors, 100k errors, etc. Could we add a field that specifies the cost for each reserved tier? then just keep base_price_cents for add-on activation fees only

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

WE talked in person:

reserved tiers are stored in reserved_rates, the comment was unhelpful because "reserverd budget line items" has a legacy connotation

Comment thread proto/sentry_protos/billing/v1/services/package/v1/package.proto Outdated
@volokluev volokluev marked this pull request as ready for review April 20, 2026 22:41
Copy link
Copy Markdown
Member

@krithikravi krithikravi left a comment

Choose a reason for hiding this comment

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

agree that BillableMetric.name and LineItemDetails.customer_facing_name are redundant because it's a 1:1 relationship anyway, otherwise lgtm

@volokluev volokluev merged commit 4746c5c into main Apr 20, 2026
12 checks passed
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.

4 participants