Skip to content

feat(store): billing invoice and subscription provider ids are unique over live rows only - #1981

Merged
rohilsurana merged 1 commit into
mainfrom
feat/billing-provider-ids-live-unique
Oct 16, 2026
Merged

rohilsurana merged 1 commit into
mainfrom
feat/billing-provider-ids-live-unique

Conversation

@rohilsurana

@rohilsurana rohilsurana commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

What changes

  • One migration. The provider_id of invoices and subscriptions is now unique over live rows only (WHERE deleted_at IS NULL).
  • The old plain unique constraints on billing_invoices.provider_id and billing_subscriptions.provider_id are dropped.
  • The redundant unique on billing_subscriptions (provider_id, plan_id) is dropped. The single column index already covers it.

Why

This is the first step of making the billing rows soft deleted when an organization is deleted. A soft deleted invoice or subscription keeps its provider id. Without this change a later sync from the billing provider could not insert the same id again, and the plain unique would also make a soft deleted row block a live one.

Nothing writes deleted_at on these tables yet, so there is no behavior change in this PR.

Release note

Safe to deploy on its own. The down migration puts the plain unique constraints back. It fails if two rows share a provider id, which can only happen after rows have been soft deleted.

Tests

  • Invoices: a soft deleted row and a live row can share a provider id. A second live row with that id is rejected.
  • Subscriptions: the same, and exactly one live row is left for the id.

@vercel

vercel Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
frontier Ready Ready Preview Oct 14, 2026 9:04am UTC

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: Repository: raystack/frontier/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b5f84af2-86f3-4285-910f-649eae3e37c8
📥 Commits

Reviewing files that changed from the base of the PR and between 8d9f641 and 89bfb1c.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Billing invoice and subscription provider IDs can now be reused after the previous record is soft-deleted.
    • Duplicate provider IDs remain disallowed when an invoice or subscription is still active.

The migration changes billing invoice and subscription provider ID uniqueness to apply only to non-deleted rows. PostgreSQL tests verify that soft-deleted provider IDs can be reused and that duplicate live rows are rejected.

Changes: Live Billing Provider ID Uniqueness

Layer / File(s) Summary
Live-row unique indexes
internal/store/postgres/migrations/20261013100000_billing_provider_ids_live_unique.up.sql, internal/store/postgres/migrations/20261013100000_billing_provider_ids_live_unique.down.sql
The up migration adds unique indexes for provider IDs on non-deleted invoices and subscriptions, and drops the existing constraints. The down migration restores those constraints and drops the indexes.
Soft-delete reuse tests
internal/store/postgres/billing_invoice_repository_pg_test.go, internal/store/postgres/billing_subscription_repository_pg_test.go
The tests verify provider ID reuse after soft deletion and reject a second live row with the same provider ID.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Merge Risk: 🟡 Moderate · up to 8d9f6

Existing instances may experience blocked billing writes during migration. Resolve the index-build approach before merging unless that rollout risk is explicitly accepted.

Pre-merge checks: Passed 2
Passed Passed checks (2 passed)
Check name Status Explanation
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.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@coveralls

coveralls commented Oct 12, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 38539605563

Coverage remained the same at 54.896%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 41544
Covered Lines: 22806
Line Coverage: 54.9%
Coverage Strength: 19.01 hits per line

💛 - Coveralls

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: raystack/frontier/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: cff0668b-60f0-45ee-a2c8-6355bd58ae0d
📥 Commits

Reviewing files that changed from the base of the PR and between 7d1a3d3 and 8d9f641.

📒 Files selected for processing (4)
  • internal/store/postgres/billing_invoice_repository_pg_test.go
  • internal/store/postgres/billing_subscription_repository_pg_test.go
  • internal/store/postgres/migrations/20261013100000_billing_provider_ids_live_unique.down.sql
  • internal/store/postgres/migrations/20261013100000_billing_provider_ids_live_unique.up.sql

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

@rohilsurana
rohilsurana merged commit 3425558 into main Oct 16, 2026
8 checks passed
@rohilsurana
rohilsurana deleted the feat/billing-provider-ids-live-unique branch October 16, 2026 08:39

This branch was successfully deployed

1 active deployment
Preview — 89bfb1c0 Deployed Oct 14, 2026 by vercel[bot]
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