Skip to content

Conversation

@turip
Copy link
Member

@turip turip commented May 26, 2025

Overview

This patch allows for synchronizing the flat fees as "usage-based" flat fees. The feature is not exposed via configuration, as this is just an interim step towards using the "usage-based" flat fees everywhere.

Previously created flat fee lines are not changed: they will be migrated using an SQL migration to the new format in a separate PR, once we have fully validated this change.

Summary by CodeRabbit

  • New Features

    • Introduced a feature flag to enable usage-based flat fee billing lines, allowing flexible transition between traditional and new billing models.
    • Added helper functions to support handling of flat fee amounts in both legacy and usage-based billing lines.
  • Bug Fixes

    • Improved error handling and validation when merging and updating billing lines.
  • Tests

    • Added comprehensive tests to ensure compatibility and correct behavior when toggling between flat fee and usage-based billing line representations.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 26, 2025

📝 Walkthrough

"""

Walkthrough

This change introduces a feature flag to enable a new usage-based representation for flat fee billing lines in the subscription billing workflow. Supporting helpers are added to manage both legacy and new line types. The merging and patching logic is refactored for type safety and error handling, and comprehensive tests ensure compatibility during the transition.

Changes

File(s) Change Summary
openmeter/billing/worker/subscription/feehelper.go Added helper functions to identify, extract, and set flat fee per-unit amounts for both legacy and usage-based billing line types.
openmeter/billing/worker/subscription/sync.go Introduced feature flag for usage-based flat fee lines; refactored line merging logic to return detailed results and errors; improved error handling.
openmeter/billing/worker/subscription/sync_test.go Added tests to verify compatibility and correct behavior when toggling the usage-based flat fee feature flag during synchronization.
"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 459091f and 38c8878.

📒 Files selected for processing (3)
  • openmeter/billing/worker/subscription/feehelper.go (1 hunks)
  • openmeter/billing/worker/subscription/sync.go (5 hunks)
  • openmeter/billing/worker/subscription/sync_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • openmeter/billing/worker/subscription/feehelper.go
  • openmeter/billing/worker/subscription/sync_test.go
  • openmeter/billing/worker/subscription/sync.go
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: CI
  • GitHub Check: Test
  • GitHub Check: Lint
  • GitHub Check: E2E
  • GitHub Check: Analyze (go)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@turip turip force-pushed the refactor/test-cleanup branch from d295485 to 9d7ba24 Compare May 27, 2025 08:35
Base automatically changed from refactor/test-cleanup to main May 27, 2025 08:47
@turip turip force-pushed the feat/use-ubp-lines-subs-sync branch 2 times, most recently from 04d1fef to 430e0b2 Compare May 27, 2025 12:28
@turip turip added release-note/feature Release note: Exciting New Features area/billing area/subscriptions labels May 27, 2025
@turip turip force-pushed the feat/use-ubp-lines-subs-sync branch from 430e0b2 to 459091f Compare May 27, 2025 12:31
@turip turip marked this pull request as ready for review May 27, 2025 12:31
@turip turip requested a review from a team as a code owner May 27, 2025 12:31
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18df036 and 459091f.

📒 Files selected for processing (3)
  • openmeter/billing/worker/subscription/feehelper.go (1 hunks)
  • openmeter/billing/worker/subscription/sync.go (5 hunks)
  • openmeter/billing/worker/subscription/sync_test.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
openmeter/billing/worker/subscription/sync_test.go (6)
pkg/clock/clock.go (2)
  • FreezeTime (33-36)
  • Now (14-21)
openmeter/productcatalog/phase.go (1)
  • PhaseMeta (18-33)
openmeter/productcatalog/ratecard.go (2)
  • UsageBasedRateCard (354-360)
  • RateCardMeta (52-83)
openmeter/billing/invoiceline.go (5)
  • InvoiceLineTypeFee (31-31)
  • Line (282-296)
  • InvoiceLineType (27-27)
  • InvoiceLineType (36-41)
  • InvoiceLineTypeUsageBased (33-33)
pkg/isodate/date.go (1)
  • MustParse (151-158)
openmeter/billing/worker/subscription/sync.go (1)
  • Handler (67-74)
⏰ Context from checks skipped due to timeout of 90000ms (11)
  • GitHub Check: CI
  • GitHub Check: Quickstart
  • GitHub Check: E2E
  • GitHub Check: Lint
  • GitHub Check: Commit hooks
  • GitHub Check: Developer environment
  • GitHub Check: Test
  • GitHub Check: Migration Checks
  • GitHub Check: Build
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (7)
openmeter/billing/worker/subscription/feehelper.go (2)

1-11: LGTM! Clean package structure and imports.

The package declaration and imports are well-structured and include all necessary dependencies for decimal handling and billing operations.


12-13: Good documentation of temporary nature.

The comment clearly explains that these are temporary helpers for the flat fee transition and should be removed after migration. This helps future developers understand the lifecycle of this code.

openmeter/billing/worker/subscription/sync_test.go (1)

3456-3539: Excellent backward compatibility test implementation!

This test thoroughly validates the UseUsageBasedFlatFeeLines feature flag behavior and ensures smooth transition from legacy flat fee lines to usage-based flat fee lines. The test design is particularly well-thought-out:

  1. Proper flag lifecycle management: The test correctly toggles the feature flag and uses a defer function to ensure cleanup
  2. Backward compatibility verification: It confirms that existing flat fee lines remain unchanged when the flag is enabled
  3. Forward compatibility testing: New lines created after flag enablement correctly use the usage-based approach
  4. Mixed state validation: The final assertion verifies that both line types can coexist, which is crucial for the migration strategy described in the PR

The test directly supports the PR objective of enabling usage-based flat fees as an interim step without disrupting existing data, and it properly validates that "existing flat fee lines created prior to this update remain unchanged."

openmeter/billing/worker/subscription/sync.go (4)

35-35: LGTM!

The feature flag addition follows the existing pattern and is appropriately named.


625-636: Proper error handling implementation!

The error handling correctly propagates errors from mergeChangesFromLine with appropriate context.


756-802:

Details

✅ Verification successful

Good refactoring with improved error handling!

The refactoring improves type safety by returning a structured result and adds proper validation for flat fee line merging. The error messages are descriptive and will help with debugging.


🏁 Script executed:

#!/bin/bash
# Description: Verify the helper functions exist and are properly implemented

# Search for the helper function definitions
ast-grep --pattern 'func isFlatFee($_) $_'
ast-grep --pattern 'func getFlatFeePerUnitAmount($_) $_'
ast-grep --pattern 'func setFlatFeePerUnitAmount($_, $_) $_'

# Check the feehelper.go file mentioned in the summary
fd -t f "feehelper.go" | xargs cat 2>/dev/null | head -50

Length of output: 5183


Approve mergeChangesFromLine refactoring

Verified that all helper functions referenced in sync.go are present and correctly implemented in openmeter/billing/worker/subscription/feehelper.go:

  • isFlatFee(line *billing.Line) bool
  • getFlatFeePerUnitAmount(line *billing.Line) (alpacadecimal.Decimal, error)
  • setFlatFeePerUnitAmount(line *billing.Line, perUnitAmount alpacadecimal.Decimal) error

These cover both InvoiceLineTypeFee and InvoiceLineTypeUsageBased cases with appropriate error handling. No further changes required.


519-533:

Details

❓ Verification inconclusive

Verify nil FeatureKey handling for flat fee lines.

When creating usage-based lines for flat fees, the code uses lo.FromPtr(item.SubscriptionItem.RateCard.AsMeta().FeatureKey). If FeatureKey is nil (which might be valid for flat fees), this will result in an empty string. Please verify that this is the intended behavior.

Additionally, there's a typo in the method name: "lineFromSubscritionRateCard" should be "lineFromSubscriptionRateCard".


🏁 Script executed:

#!/bin/bash
# Description: Check if FeatureKey can be nil for flat fee rate cards

# Search for flat fee rate card definitions and their FeatureKey usage
ast-grep --pattern 'type $_ struct {
  $$$
  FeatureKey $_
  $$$
}'

# Search for flat fee creation patterns to understand FeatureKey requirements
rg -A 5 -B 5 "FlatPrice.*FeatureKey"

Length of output: 67916


Verify nil FeatureKey handling under UseUsageBasedFlatFeeLines.

  • Confirm that item.SubscriptionItem.RateCard.AsMeta().FeatureKey is always non-nil when UseUsageBasedFlatFeeLines is enabled. If it can be nil, you’ll end up with an empty string in the invoice line’s FeatureKey. Consider falling back to RateCardMeta.Key or explicitly erroring/handling the nil case.
  • Rename the helper from lineFromSubscritionRateCardlineFromSubscriptionRateCard to fix the typo.

@turip turip force-pushed the feat/use-ubp-lines-subs-sync branch from 459091f to 38c8878 Compare May 27, 2025 13:46
@turip turip requested a review from GAlexIHU May 27, 2025 13:56
@turip turip merged commit e8a0865 into main May 27, 2025
23 checks passed
@turip turip deleted the feat/use-ubp-lines-subs-sync branch May 27, 2025 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants