Skip to content

fix(customer): list customers for default billing profile when filtered#4369

Merged
tothandras merged 2 commits into
mainfrom
fix/customer-filter-billing-profiles
May 16, 2026
Merged

fix(customer): list customers for default billing profile when filtered#4369
tothandras merged 2 commits into
mainfrom
fix/customer-filter-billing-profiles

Conversation

@tothandras
Copy link
Copy Markdown
Contributor

@tothandras tothandras commented May 15, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Customer listing now correctly resolves and applies namespace default billing profiles alongside per-customer overrides, ensuring filters match fallback, explicit, and soft-deleted override cases.
  • Tests

    • Added end-to-end tests verifying billing-profile filtering behavior across default, explicit, null (fallback), pinned, and soft-deleted override scenarios.

Review Change Stack

@tothandras tothandras requested a review from a team as a code owner May 15, 2026 19:29
@tothandras tothandras added the release-note/bug-fix Release note: Bug Fixes label May 15, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a053adc0-708e-4d42-b3fe-ee2cedfb561b

📥 Commits

Reviewing files that changed from the base of the PR and between dd453df and 90fc007.

📒 Files selected for processing (1)
  • openmeter/customer/adapter/customer.go

📝 Walkthrough

Walkthrough

The PR enhances customer listing to intelligently resolve each customer's effective billing profile: if a customer has an override, use that; otherwise, fall back to the namespace default. The implementation introduces two helpers that build dynamic SQL predicates, and comprehensive test coverage validates the behavior across override states.

Changes

Billing Profile Filtering for Customer List

Layer / File(s) Summary
Core billing profile filtering logic and helpers
openmeter/customer/adapter/customer.go
ListCustomers now computes the namespace default billing profile ID and routes the BillingProfileID filter through a new predicate that checks customer override rows first, or matches the default via an EXISTS subquery if no override exists. Two unexported helpers handle the default lookup and predicate construction, including NULL override fallback semantics.
Test suite for billing profile filtering
test/customer/customer.go, test/customer/customer_test.go
New test method TestListBillingProfileFilter provisions a default profile, creates customers with varying override states (none, NULL, pinned to default, pinned to alternate, soft-deleted), and verifies ListCustomers filtering accuracy for both default and explicit profile IDs. Test is wired into the suite as a subtest.

🎯 3 (Moderate) | ⏱️ ~20 minutes


area/billing

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main fix: resolving the caller's BillingProfileID filter to include default billing profile customers, which is the core change across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/customer-filter-billing-profiles

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
test/customer/customer.go (1)

789-815: ⚡ Quick win

Nice coverage — consider tossing in Ne/In cases too.

The two eq subtests nail the main bug, but the dual-branch predicate (override vs. default fallback) also flows through Ne, In, and the And/Or wrappers. SQL three-valued logic on billing_profile_id IS NULL in the override branch is a subtle spot — a quick Ne pinned case (where customers with IS NULL overrides should still be included via the default branch) would lock that behavior in place against future regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/customer/customer.go` around lines 789 - 815, Add tests exercising
negative and set membership cases for the dual-branch billing_profile_id
predicate: add a t.Run("ne pinned") that calls customerService.ListCustomers
with BillingProfileID: &filter.FilterULID{FilterString: filter.FilterString{Ne:
&pinnedProfile.ID}} and assert that customers with NULL overrides still match
via the default branch (expect IDs: noOverride.ID, overrideNullProfile.ID,
overrideDefault.ID, overrideSoftDeleted.ID); also add a t.Run("in
pinned,default") using FilterULID{FilterString: filter.FilterString{In:
&[]ulid.ULID{pinnedProfile.ID, defaultProfile.ID}}} and assert the appropriate
set of IDs (including overridePinned when pinned is present and default-fallback
matches others); mirror similar cases under And/Or wrappers if present to lock
behavior around SQL three-valued NULL handling for BillingProfileID in
customer.ListCustomers and associated predicate logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/customer/customer.go`:
- Around line 789-815: Add tests exercising negative and set membership cases
for the dual-branch billing_profile_id predicate: add a t.Run("ne pinned") that
calls customerService.ListCustomers with BillingProfileID:
&filter.FilterULID{FilterString: filter.FilterString{Ne: &pinnedProfile.ID}} and
assert that customers with NULL overrides still match via the default branch
(expect IDs: noOverride.ID, overrideNullProfile.ID, overrideDefault.ID,
overrideSoftDeleted.ID); also add a t.Run("in pinned,default") using
FilterULID{FilterString: filter.FilterString{In: &[]ulid.ULID{pinnedProfile.ID,
defaultProfile.ID}}} and assert the appropriate set of IDs (including
overridePinned when pinned is present and default-fallback matches others);
mirror similar cases under And/Or wrappers if present to lock behavior around
SQL three-valued NULL handling for BillingProfileID in customer.ListCustomers
and associated predicate logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6ec51bfb-e79e-4ab6-a809-4666465bd5a7

📥 Commits

Reviewing files that changed from the base of the PR and between 6f51b29 and dd453df.

📒 Files selected for processing (3)
  • openmeter/customer/adapter/customer.go
  • test/customer/customer.go
  • test/customer/customer_test.go

turip
turip previously approved these changes May 15, 2026
Comment thread openmeter/customer/adapter/customer.go Outdated
@tothandras tothandras merged commit daa002d into main May 16, 2026
25 checks passed
@tothandras tothandras deleted the fix/customer-filter-billing-profiles branch May 16, 2026 06:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/bug-fix Release note: Bug Fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants