Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
syntax = "proto3";

package sentry_protos.billing.v1.services.usage_pricer.v1;

import "sentry_protos/billing/v1/date.proto";
import "sentry_protos/billing/v1/usage_data.proto";

// Compiles per-day, per-line-item usage breakdowns spanning one or more
// contracts. UsagePricer evaluates each contract's package
// ``BillableMetric.expression`` once per outcome field of the raw
// usage, so callers receive the package-projected ``UsageData`` view
// rather than the raw outcomes returned by ``BillingUsageService``.
//
// This is the "non-pricing" derived view UsagePricer exposes -- the
// projection step pricing already performs internally, lifted out so
// other presentation services (e.g. ChargeService for CSV / UI) can
// consume it without re-implementing evaluation.
message GetDailyBreakdownRequest {
// The contracts whose daily breakdowns should be returned.
repeated string contract_ids = 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Contract IDs use wrong type

High Severity

GetDailyBreakdownRequest declares contract_ids as repeated string, while contract identifiers elsewhere in billing protos (including GetPriceForContractRequest and Contract metadata) are uint64. Callers and implementations that follow the established contract API will use the wrong wire type and field encoding for this request.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2060a5f. Configure here.

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 kind of think we should start using string, we can always represent a uint64 as a string


// One line item's projected per-outcome quantities on a given date.
message LineItemDailyOutcomes {
// Package line item uid (UsagePricer's native vocabulary).
string line_item_uid = 1;

// The seven outcome fields, each populated by evaluating the line
// item's ``BillableMetric.expression`` against that outcome's raw
// counts in the day's usage.
sentry_protos.billing.v1.UsageData outcomes = 2;
}

// One row per calendar date spanning the union of the requested
// contracts' on-demand periods.
message DailyLineItemOutcomes {
sentry_protos.billing.v1.Date date = 1;

// Per-line-item outcomes on this date. Every metered line item from
// the union of the requested contracts' packages is emitted,
// including line items with zero usage, so consumers can render
// zero-rows without a separate zero-fill pass.
repeated LineItemDailyOutcomes line_items = 2;
}

message GetDailyBreakdownResponse {
// Days in ascending date order. A given calendar date appears at
// most once regardless of how many of the requested contracts
// overlap it (BillingUsageService reports usage at calendar-day
// granularity, so a day straddling a mid-day rollover is still one
// row carrying the day's full outcomes). Contract ids from the
// request that do not resolve contribute no rows.
repeated DailyLineItemOutcomes days = 1;
}
5 changes: 5 additions & 0 deletions rust/src/sentry_protos.billing.v1.services.contract.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ pub struct BillingConfig {
/// (1 = monthly, 12 = annual). Frozen for the life of the contract.
#[prost(uint32, tag = "7")]
pub month_interval: u32,
/// Whether the org is allowed to incur pay-as-you-go usage.
/// Credit-card orgs always support payg; invoiced orgs that should
/// support it are an explicit override.
#[prost(bool, tag = "8")]
pub supports_payg: bool,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Rust field missing proto source

Medium Severity

Generated BillingConfig in Rust adds supports_payg at tag 8, but billing_config.proto stops at month_interval (tag 7) with no supports_payg definition. Regenerating bindings from the committed protos drops this field, so Rust, Python, and the canonical proto schema disagree on BillingConfig.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2060a5f. Configure here.

}
/// Indicates how the account is billed.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
Expand Down
52 changes: 52 additions & 0 deletions rust/src/sentry_protos.billing.v1.services.usage_pricer.v1.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,56 @@
// This file is @generated by prost-build.
/// Compiles per-day, per-line-item usage breakdowns spanning one or more
/// contracts. UsagePricer evaluates each contract's package
/// `BillableMetric.expression` once per outcome field of the raw
/// usage, so callers receive the package-projected `UsageData` view
/// rather than the raw outcomes returned by `BillingUsageService`.
///
/// This is the "non-pricing" derived view UsagePricer exposes -- the
/// projection step pricing already performs internally, lifted out so
/// other presentation services (e.g. ChargeService for CSV / UI) can
/// consume it without re-implementing evaluation.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct GetDailyBreakdownRequest {
/// The contracts whose daily breakdowns should be returned.
#[prost(string, repeated, tag = "1")]
pub contract_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
/// One line item's projected per-outcome quantities on a given date.
#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
pub struct LineItemDailyOutcomes {
/// Package line item uid (UsagePricer's native vocabulary).
#[prost(string, tag = "1")]
pub line_item_uid: ::prost::alloc::string::String,
/// The seven outcome fields, each populated by evaluating the line
/// item's `BillableMetric.expression` against that outcome's raw
/// counts in the day's usage.
#[prost(message, optional, tag = "2")]
pub outcomes: ::core::option::Option<super::super::super::UsageData>,
}
/// One row per calendar date spanning the union of the requested
/// contracts' on-demand periods.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct DailyLineItemOutcomes {
#[prost(message, optional, tag = "1")]
pub date: ::core::option::Option<super::super::super::Date>,
/// Per-line-item outcomes on this date. Every metered line item from
/// the union of the requested contracts' packages is emitted,
/// including line items with zero usage, so consumers can render
/// zero-rows without a separate zero-fill pass.
#[prost(message, repeated, tag = "2")]
pub line_items: ::prost::alloc::vec::Vec<LineItemDailyOutcomes>,
}
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetDailyBreakdownResponse {
/// Days in ascending date order. A given calendar date appears at
/// most once regardless of how many of the requested contracts
/// overlap it (BillingUsageService reports usage at calendar-day
/// granularity, so a day straddling a mid-day rollover is still one
/// row carrying the day's full outcomes). Contract ids from the
/// request that do not resolve contribute no rows.
#[prost(message, repeated, tag = "1")]
pub days: ::prost::alloc::vec::Vec<DailyLineItemOutcomes>,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
pub struct UsagePricerRequest {
#[prost(uint64, tag = "1")]
Expand Down