Skip to content

fix: populate payment_mode in organization search results#1491

Merged
rohilsurana merged 9 commits intomainfrom
fix/org-search-payment-mode
Mar 31, 2026
Merged

fix: populate payment_mode in organization search results#1491
rohilsurana merged 9 commits intomainfrom
fix/org-search-payment-mode

Conversation

@rohilsurana
Copy link
Copy Markdown
Member

Summary

  • Fixes the empty "Payment Mode" column in the admin organizations list page
  • Computes payment_mode as a derived SQL column from billing_customers.provider_id — no schema migration needed

What changed

internal/store/postgres/org_billing_repository.go:

  • Added COLUMN_PAYMENT_MODE constant
  • Added a CASE expression in getSubQuery() that derives payment mode from billing_customers.provider_id:
    • provider_id IS NULL or empty → "prepaid" (offline/no billing provider)
    • provider_id present → "postpaid" (registered with Stripe/billing provider)
  • Added payment_mode to data query selects, supported filters, and group-by keys

Context

The payment_mode field was added to the proto contract and wired through all Go layers (handler, service model, repository struct) in #877 but the SQL query never selected it, so it always returned empty.

Test plan

  • go build ./... passes
  • Query /admin/v1beta1/organizations/searchpayment_mode field returns "prepaid" or "postpaid" for each org
  • Admin UI organizations list shows correct Payment Mode column values
  • Filtering by payment_mode works

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
frontier Ready Ready Preview, Comment Mar 31, 2026 9:44am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a computed payment_mode column end-to-end: migration introduces a payment_mode_type enum and a stored generated payment_mode on billing_customers; the org billing repository exposes payment_mode for selection, grouping, and RQL filtering; tests updated to expect the new column.

Changes

Cohort / File(s) Summary
Repository query
internal/store/postgres/org_billing_repository.go
Includes payment_mode in base SELECT, permits payment_mode as a group_by key, and adds RQL filter support for payment_mode.
Tests
internal/store/postgres/org_billing_repository_test.go
Updated expected SQL to project payment_mode in the outer SELECT and to select billing_customers.payment_mode AS "payment_mode" in the inner ranked subquery across relevant tests.
Migrations (up/down)
internal/store/postgres/migrations/20260331100000_billing_customer_payment_mode.up.sql, internal/store/postgres/migrations/20260331100000_billing_customer_payment_mode.down.sql
Up migration creates enum payment_mode_type (prepaid,postpaid) and adds a stored generated billing_customers.payment_mode (CASE on credit_min: negative → 'postpaid', else 'prepaid'); down migration drops the column and the enum type if they exist.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • rsbh

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)
internal/store/postgres/org_billing_repository.go (1)

299-302: Normalize provider_id before classification to avoid whitespace edge cases.

provider_id = '' misses values like ' ', which would currently be treated as postpaid. Consider trimming + nullifying before the CASE check.

♻️ Suggested SQL expression hardening
-		goqu.L(fmt.Sprintf(
-			"CASE WHEN %s.provider_id IS NULL OR %s.provider_id = '' THEN 'prepaid' ELSE 'postpaid' END",
-			TABLE_BILLING_CUSTOMERS, TABLE_BILLING_CUSTOMERS,
-		)).As(COLUMN_PAYMENT_MODE),
+		goqu.L(fmt.Sprintf(
+			"CASE WHEN NULLIF(BTRIM(%s.provider_id), '') IS NULL THEN 'prepaid' ELSE 'postpaid' END",
+			TABLE_BILLING_CUSTOMERS,
+		)).As(COLUMN_PAYMENT_MODE),

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4faa3096-b11e-42dd-9b86-08d017088a09

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3f564 and 4db7758.

📒 Files selected for processing (1)
  • internal/store/postgres/org_billing_repository.go

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/store/postgres/org_billing_repository_test.go (1)

29-44: ⚠️ Potential issue | 🟡 Minor

Missing targeted regression cases for payment_mode filter/group-by.

The updated expectations include payment_mode, but there is no explicit test case for filtering by payment_mode or grouping by payment_mode. Given this PR’s scope, those two scenarios should be asserted directly.

Suggested additions
+ {
+   name: "query with payment_mode filter",
+   rqlQuery: &rql.Query{
+     Filters: []rql.Filter{{Name: "payment_mode", Operator: "eq", Value: "postpaid"}},
+     Limit: 10, Offset: 0,
+   },
+   // wantSQL / wantParameters for payment_mode predicate
+   wantErr: false,
+ },
...
+ {
+   name: "group by payment_mode",
+   rqlQuery: &rql.Query{GroupBy: []string{"payment_mode"}},
+   // wantSQL / wantParameters for GROUP BY "payment_mode"
+   wantErr: false,
+ },

Also applies to: 147-164

🧹 Nitpick comments (1)
internal/store/postgres/org_billing_repository_test.go (1)

24-106: Consider reducing duplicated full SQL literals in test cases.

These long repeated SQL strings are hard to maintain and easy to desync when query internals change. A shared base SQL fragment/helper would keep these tests easier to update and less error-prone.

Also applies to: 152-161


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 65ab0b83-b0df-423f-b1a5-9f8b69cbaa60

📥 Commits

Reviewing files that changed from the base of the PR and between d58dc4f and 2f19ff7.

📒 Files selected for processing (1)
  • internal/store/postgres/org_billing_repository_test.go

@coveralls
Copy link
Copy Markdown

coveralls commented Mar 31, 2026

Pull Request Test Coverage Report for Build 23790959167

Details

  • 4 of 4 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.007%) to 41.675%

Totals Coverage Status
Change from base Build 23784870790: 0.007%
Covered Lines: 15052
Relevant Lines: 36118

💛 - Coveralls

Compute payment_mode as a derived column in the org billing search
query based on billing_customers.provider_id: orgs without a billing
provider are "prepaid", orgs with one are "postpaid". The field was
defined in proto and wired through all layers but never selected in
the SQL query, so it always returned empty.
Postpaid if billing_customers.credit_min is defined and positive
(customer has a credit limit), prepaid otherwise.
Add a GENERATED ALWAYS STORED column on billing_customers that derives
payment_mode from credit_min (negative = postpaid, else prepaid). The
query now reads the column directly instead of computing it inline.
@rohilsurana rohilsurana merged commit ef91d56 into main Mar 31, 2026
8 checks passed
@rohilsurana rohilsurana deleted the fix/org-search-payment-mode branch March 31, 2026 10:12
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.

3 participants