Skip to content

feat(store): billing subscription and checkout reads skip soft-deleted rows - #1963

Draft
rohilsurana wants to merge 2 commits into
mainfrom
soft-delete-billing-subscriptions-checkouts
Draft

rohilsurana wants to merge 2 commits into
mainfrom
soft-delete-billing-subscriptions-checkouts

Conversation

@rohilsurana

@rohilsurana rohilsurana commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Summary

The billing subscription and checkout repositories read rows without checking deleted_at. They now skip deleted rows, using the same live and fromLive helpers as the rest of the store.

These are the last two of the five repositories the org delete cascade touches. #1962 does the other three and is still open, so all five only filter once both land. Nothing writes deleted_at to either table yet, so every read returns the same rows as before.

Changes

  • Subscriptions: GetByID, GetByName, GetByProviderID and List now read from fromLive.
  • Checkouts: GetByID, GetByName and List now read from fromLive.
  • A new postgres-backed test suite for each.

Technical Details

The two correlated subqueries on billing_customers in the subscription repository are left alone on purpose. They only fill the org id and customer name into the RETURNING clause of Create and UpdateByID, for the audit record. Filtering them would do more than blank two columns: both fields are plain strings, so a NULL would fail the struct scan and abort the whole write. An audit record should say which org a subscription belonged to even after the customer is deleted.

GetByName on both repositories is unreachable. Neither table has a name column and neither method has a caller, so calling either fails with a postgres error before deleted_at matters. I filtered them to keep the files consistent, but they are dead code and deleting them would be a fair follow-up.

The update paths and the hard deletes are untouched, matching #1962.

No migration. Subscriptions have carried deleted_at since the table was created, and checkouts got it in 20260916100000_soft_delete_columns.

Test Plan

  • go test -run 'TestBillingSubscriptionRepositoryPG|TestBillingCheckoutRepositoryPG' ./internal/store/postgres/ passes
  • Both suites fail on main
  • golangci-lint run ./internal/store/postgres/... reports no issues
  • go test ./internal/store/postgres/ ./billing/... passes

Each suite seeds a live row and a deleted one, and I watched all five tests fail before adding the filters. Reverting the seven fromLive calls was also checked: every test fails, and each test exercises exactly one read, so each one catches its own change.

SQL Safety (if your PR touches *_repository.go or goqu.*)

  • Values flow through ? placeholders, goqu.Ex{}, or goqu.Record{} — never fmt.Sprintf or + building a query that gets executed.
  • ToSQL() callers capture and forward params (query, params, err := stmt.ToSQL(); db.…Context(ctx, …, query, params...)). Never query, _, err := ….
  • No ? placeholders inside single-quoted SQL literals in goqu.L (use make_interval(hours => ?)-style functions instead).
  • Any //nolint:forbidigo or // #nosec G20x annotation has a one-line justification on the same line that a reviewer can verify.

The added predicates come from the existing live() helper and bind no values. The only fmt.Sprintf in the diff builds TRUNCATE in the test teardowns from package table constants, the same as the other suites here.

@vercel

vercel Bot commented Sep 30, 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 Sep 30, 2026 2:00pm UTC

@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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

Copy link
Copy Markdown

Coverage Report for CI Build 36725725341

Coverage increased (+0.4%) to 53.41%

Details

  • Coverage increased (+0.4%) from the base build.
  • Patch coverage: 2 uncovered changes across 2 files (5 of 7 lines covered, 71.43%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
internal/store/postgres/billing_checkout_repository.go 3 2 66.67%
internal/store/postgres/billing_subscription_repository.go 4 3 75.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 41348
Covered Lines: 22084
Line Coverage: 53.41%
Coverage Strength: 17.1 hits per line

💛 - Coveralls

This branch was successfully deployed

1 active deployment
Preview — ec2e29d5 Deployed Sep 30, 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.

2 participants