Skip to content

feat(billing): Add BillingService base class and service method decorator#109376

Merged
volokluev merged 5 commits intomasterfrom
volo/billing/service_shim
Feb 26, 2026
Merged

feat(billing): Add BillingService base class and service method decorator#109376
volokluev merged 5 commits intomasterfrom
volo/billing/service_shim

Conversation

@volokluev
Copy link
Copy Markdown
Member

@volokluev volokluev commented Feb 25, 2026

Human Stuff

This code was generated using the file in src/sentry/billing/platform/INTENTION.md. This is meant as a starting point for us to build from. No existing logic is modified, the services do not exist yet.

I checked over the implementation of the base class and tests and it seems sane to me.

Reviewer task

  1. Does the intention align with what you think of as the project direction?
  2. Does the interface seem reasonable enough as the primitive we will use to call services.

If yes, click approve

Robot Stuff

Implement core primitives for the new billing platform to establish the foundation for service-oriented architecture where billing services communicate through well-defined protobuf interfaces.

What's included

This PR adds:

  • BillingService base class: Foundation for all billing services with uniform construction (no __init__ arguments)
  • @service_method decorator: Provides observability, type validation, and structured logging for service methods
  • Comprehensive test suite: 15 tests demonstrating usage patterns and validating functionality
  • Documentation: README files explaining design principles and usage

Why these changes

The existing billing code in getsentry/services/billing has grown into a spaghetti codebase. This PR starts the rewrite by establishing well-defined service boundaries and interfaces.

Following the principles in INTENTION.md:

  • Services have uniform construction (no __init__ arguments)
  • All interfaces use protobuf messages for strong typing
  • Service methods automatically log start/success/error events with timing
  • Services will eventually delegate to external RPC endpoints

Architecture

The folder structure enforces separation:

  • core/ - Contains core primitives, no application logic
  • services/ - Each service in its own directory, no cross-service imports

Services communicate exclusively through the BillingService abstraction, making it straightforward to later move implementations to external services.

Next steps

Future PRs will:

  1. Add individual billing services (contract, usage, etc.)
  2. Define protobuf schemas for service interfaces
  3. Gradually migrate existing billing logic to the new architecture

…ator

Implement core primitives for the new billing platform. This establishes
the foundation for service-oriented architecture where billing services
communicate through well-defined protobuf interfaces.

Key components:
- BillingService: Base class for all billing services with uniform
  construction (no __init__ arguments)
- @service_method: Decorator providing observability, type validation,
  and structured logging for service methods
- Comprehensive tests demonstrating usage patterns

The implementation follows principles from INTENTION.md:
- Services have no __init__ arguments for uniformity
- All interfaces use protobuf messages for strong typing
- Service methods automatically log start/success/error with timing
- Services will eventually delegate to external RPC endpoints

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 25, 2026
@@ -0,0 +1,3 @@
from .service import BillingService, service_method
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.

no relative imports

- Add metrics tracking for service method calls, success, errors, and duration
- Fix relative imports in __init__.py to use absolute imports
- Simplify tests from 15 to 6, removing redundant test cases while
  maintaining full coverage of essential behavior

Co-Authored-By: Claude <noreply@anthropic.com>
volokluev and others added 2 commits February 25, 2026 13:32
Consolidated three READMEs to eliminate repeated information:
- platform/README.md: High-level overview and quick start
- core/README.md: Focus on @service_method decorator features
- services/README.md: Service boundaries and structure guidelines

Removed duplicate examples, testing info, and future direction sections.

Co-Authored-By: Claude <noreply@anthropic.com>
Add type: ignore comments to tests that intentionally pass invalid types
to verify runtime validation. These are expected TypeErrors that mypy
should not flag.

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

@cursor cursor bot left a comment

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.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@volokluev volokluev merged commit c5cfeb2 into master Feb 26, 2026
81 checks passed
@volokluev volokluev deleted the volo/billing/service_shim branch February 26, 2026 01:09
@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants