Skip to content

feat(billing): Add seat activity and seats service protos - #411

Open
volokluev wants to merge 7 commits into
mainfrom
volo/seat_service
Open

feat(billing): Add seat activity and seats service protos#411
volokluev wants to merge 7 commits into
mainfrom
volo/seat_service

Conversation

@volokluev

@volokluev volokluev commented Aug 25, 2026

Copy link
Copy Markdown
Member

Summary

Adds proto definitions for two new billing services:

seat_activity service

  • CloseContract - close a seat contract
  • GetOriginalSeatDates - get original creation dates for seats
  • GetSeatActivityHistory - get seat activity history for a contract
  • GetSeatContractState - check if a seat contract exists and is active
  • GetSeatState - get the current state of a seat
  • PerformSeatActions - perform batch seat actions

seats service

  • AssignSeat - assign a seat
  • CheckAssignSeats - check if seats can be assigned
  • DisableSeat - disable a seat
  • GetDailySeatUsage - get daily seat usage
  • GetDailySeatUsageByProject - get daily seat usage by project
  • GetSeatStatusForExternalProduct - get seat status for an external product
  • RemoveSeat - remove a seat
  • RolloverSeatsToNewContract - rollover seats to a new contract
  • UpdateSeatIdentifier - update a seat identifier

Shared types

  • SeatStatus (consolidated into billing/v1/common/v1/seat_status.proto — shared by both services)
  • SeatObject, SeatState, SeatActionRecord, ExternalProductSeatActivity, SeatActionItem, OriginalSeatDate
  • SeatAssignmentOutcome, ProjectSeatUsage

Dependencies

  • Depended on by: getsentry/getsentry#21644 — must be merged and released first

- Add seat_activity service endpoints: close_contract, get_original_seat_dates,
  get_seat_activity_history, get_seat_contract_state, get_seat_state, perform_seat_actions
- Add seats service endpoints: assign_seat, check_assign_seats, disable_seat,
  get_daily_seat_usage, get_daily_seat_usage_by_project, get_seat_status,
  remove_seat, rollover_seats, update_seat_identifier
- Define shared types: SeatStatus, SeatObject, SeatState, SeatActionRecord,
  ExternalProductSeatActivity, SeatActionItem, OriginalSeatDate,
  ExternalProductSeatStatus, SeatAssignmentOutcome, ProjectSeatUsage
@github-actions

github-actions Bot commented Aug 25, 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✅ passedAug 28, 2026, 9:39 PM

getsantry Bot and others added 4 commits August 25, 2026 00:14
Move SeatStatus into billing/v1/common/v1/seat_status.proto so both
seat_activity and seats services share one enum. Remove the duplicate
ExternalProductSeatStatus from seats/v1/seats.proto.
Add documentation comments to all seat_activity and seats service proto
messages explaining what each endpoint does, its constraints, and any
notable behavior (e.g. OVER_QUOTA -> DISABLED mapping, idempotent
rollover, high-throughput check-in path).
@volokluev
volokluev marked this pull request as ready for review August 28, 2026 18:25
@volokluev
volokluev requested a review from a team as a code owner August 28, 2026 18:25

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 092a501. Configure here.

uint64 project_id = 3;
google.protobuf.Timestamp timestamp = 4;
sentry_protos.billing.v1.common.v1.SeatStatus status = 5;
uint32 seat_category = 6;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Seat category uses raw integer type

Medium Severity

SeatActionRecord.seat_category is a uint32 while every other seat-category field in this change uses the SeatCategory enum, including SeatObject in the same file. Callers get a raw number instead of a typed value, and changing the field later is a breaking generated-code change.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 092a501. Configure here.

Comment on lines +54 to +57

// Input item for PerformSeatActions: pairs a seat with its desired new state.
message SeatActionItem {
SeatObject seat_object = 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.

Bug: The SeatActionItem message incorrectly uses the SeatState read-model for input, creating ambiguity with a duplicated external_product_identifier and requiring clients to send meaningless server-generated fields.
Severity: MEDIUM

Suggested Fix

Refactor SeatActionItem to not embed the SeatState read-model. Instead, it should accept only the necessary input fields directly, such as the seat_object and the desired current_status. This removes the ambiguity of the duplicate identifier and eliminates the need for clients to send meaningless server-generated timestamp fields.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
proto/sentry_protos/billing/v1/services/seat_activity/v1/seat_activity.proto#L54-L57

Potential issue: The `SeatActionItem` message incorrectly uses `SeatState`, a
read-model, as an input for a write operation. This forces clients to provide
meaningless server-generated values like `read_ts`. More critically, it duplicates the
`external_product_identifier` field, which is also present in the `seat_object` field.
The schema provides no guidance on how to resolve conflicts if these two identifiers
differ, creating ambiguity for the server implementation and potential for subtle bugs.

Did we get this right? 👍 / 👎 to inform future reviews.

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.

1 participant