Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@BilalG1
Copy link
Contributor

@BilalG1 BilalG1 commented Oct 4, 2025

High-level PR Summary

This PR fixes a bug where ungrouped offers with include-by-default pricing were not being automatically included in subscription lists. The fix ensures that ungrouped default offers are now properly added to the subscriptions array when no explicit database subscription exists for them, matching the existing behavior for grouped offers. Additionally, it adds validation to prevent multiple include-by-default offers from being configured within the same group.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 apps/backend/src/lib/payments.tsx
2 apps/backend/src/lib/payments.test.tsx

Need help? Join our Discord


Important

Fixes bug to include ungrouped include-by-default offers in subscriptions and adds validation for multiple offers in the same group.

  • Behavior:
    • Fixes bug in getSubscriptions() in payments.tsx to include ungrouped include-by-default offers in subscriptions when no explicit subscription exists.
    • Adds validation in getSubscriptions() to prevent multiple include-by-default offers in the same group.
  • Tests:
    • Adds test cases in payments.test.tsx to verify inclusion of ungrouped include-by-default offers and validation of multiple offers in the same group.
  • Misc:
    • Updates import in payments.test.tsx to include getSubscriptions.

This description was created by Ellipsis for 565acc3. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features

    • Subscriptions now automatically include eligible “include-by-default” items even when they aren’t tied to a catalog, granting access without requiring an explicit subscription.
    • Consistent handling of catalog-level default items when no prior subscriptions exist.
  • Improvements

    • Expanded subscriptions data to ensure all applicable default products are surfaced to users.
  • Tests

    • Added comprehensive tests for default-inclusion behavior and edge cases to improve reliability.

@vercel
Copy link

vercel bot commented Oct 4, 2025

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

Project Deployment Preview Comments Updated (UTC)
stack-backend Ready Ready Preview Comment Oct 6, 2025 9:51pm
stack-dashboard Ready Ready Preview Comment Oct 6, 2025 9:51pm
stack-demo Ready Ready Preview Comment Oct 6, 2025 9:51pm
stack-docs Ready Ready Preview Comment Oct 6, 2025 9:51pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 4, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds logic in getSubscriptions to include ungrouped include-by-default products as active subscriptions. Updates tests to cover ungrouped default behavior and default handling in getSubscriptions. Exports getSubscriptions from the payments module and updates test imports accordingly.

Changes

Cohort / File(s) Summary
Payments logic
apps/backend/src/lib/payments.tsx
Extends getSubscriptions to inject ungrouped include-by-default products as active default subscriptions when not already present; complements existing catalog-default handling.
Tests
apps/backend/src/lib/payments.test.tsx
Adds tests for ungrouped include-by-default quantity behavior and new getSubscriptions default handling, including error path for multiple defaults in a group; updates imports to include getSubscriptions.
Public API surface
apps/backend/src/lib/payments.tsx, apps/backend/src/lib/payments.test.tsx
Module now exports getSubscriptions in addition to existing functions; tests adjusted to import it.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Caller
  participant P as payments.getSubscriptions
  participant DB as Database
  participant CAT as Catalog Rules

  C->>P: getSubscriptions(customerId)
  P->>DB: Fetch existing subscriptions
  DB-->>P: Subscriptions[]
  P->>CAT: Determine include-by-default products (grouped)
  CAT-->>P: Default products by catalog
  P->>P: Merge catalog-defaults when no prior subs
  alt Ungrouped include-by-default products
    P->>CAT: Find ungrouped defaults (no catalogId)
    CAT-->>P: Ungrouped defaults
    P->>P: Inject as active subscriptions if not present
  end
  P-->>C: Final Subscriptions[]
  note over P: New step adds ungrouped defaults
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A thump of paws, a hop of cheer,
Default goodies now appear!
Grouped or free, they join the queue,
Subscriptions fresh as morning dew.
I nibble tests with tidy bites—
All paths covered, day and nights.
ʕ•ᴥ•ʔ …oops, wrong warren—(=^.^=) hop!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly describes the primary change by indicating a fix for the handling of ungrouped include-by-default offers, directly reflecting the main behavior update in the pull request without extraneous detail.
Description Check ✅ Passed The description includes the required contributing guidelines comment from the repository template and provides a comprehensive high-level summary, detailed behavior changes, test updates, and validation information that align with the PR objectives and template structure.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-ungrouped-include-by-default

📜 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 3400f32 and d188b31.

📒 Files selected for processing (2)
  • apps/backend/src/lib/payments.test.tsx (3 hunks)
  • apps/backend/src/lib/payments.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer ES6 Map over Record when representing key–value collections

Files:

  • apps/backend/src/lib/payments.tsx
  • apps/backend/src/lib/payments.test.tsx
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

In tests, prefer .toMatchInlineSnapshot where possible; refer to snapshot-serializer.ts for snapshot formatting and handling of non-deterministic values

Files:

  • apps/backend/src/lib/payments.test.tsx
🧬 Code graph analysis (2)
apps/backend/src/lib/payments.tsx (1)
packages/stack-shared/src/utils/objects.tsx (1)
  • typedEntries (263-265)
apps/backend/src/lib/payments.test.tsx (1)
apps/backend/src/lib/payments.tsx (2)
  • getItemQuantityForCustomer (138-237)
  • getSubscriptions (264-338)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build (22.x)
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: build (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: setup-tests
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: docker
  • GitHub Check: Vercel Agent Review
  • GitHub Check: Security Check
🔇 Additional comments (3)
apps/backend/src/lib/payments.test.tsx (3)

3-3: LGTM!

The import correctly includes getSubscriptions to support the new test coverage.


721-751: LGTM!

The test correctly verifies that ungrouped include-by-default products provide item quantities without requiring a database subscription. The test setup is clear and assertions are appropriate.


970-1013: LGTM!

The test properly verifies that ungrouped include-by-default offers are automatically included in the subscriptions list. Test setup and assertions are appropriate.


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
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

This PR addresses a critical bug in the payments system where ungrouped offers with 'include-by-default' pricing were not being properly included in customer subscriptions. The core issue was that the existing logic only handled grouped default offers but completely missed ungrouped ones, potentially causing free tier or default features to be unavailable to customers who should have automatic access.

The fix operates within Stack Auth's payments infrastructure, which manages subscription offers that can be either grouped or ungrouped. Offers marked as 'include-by-default' should automatically appear in a customer's subscription without requiring explicit purchase - this is typically used for free tiers or baseline features. The payment system's getSubscriptions function is responsible for aggregating both explicitly purchased subscriptions and these automatic default offers.

The changes enhance the subscription calculation logic by:

  1. Adding validation to prevent configuration errors where multiple 'include-by-default' offers exist within the same group
  2. Implementing proper handling for ungrouped default offers by filtering offers where groupId is undefined and prices is 'include-by-default'
  3. Automatically adding these ungrouped default offers as active subscriptions with appropriate default values

The implementation integrates seamlessly with the existing payments architecture, maintaining backward compatibility while extending functionality to cover the previously missed edge case of ungrouped default offers.

Important Files Changed

Changed Files
Filename Score Overview
apps/backend/src/lib/payments.tsx 4/5 Fixed critical bug where ungrouped 'include-by-default' offers were not included in subscriptions, added validation for multiple default offers in same group
apps/backend/src/lib/payments.test.tsx 5/5 Added comprehensive test coverage for ungrouped default offers functionality and validation logic

Confidence score: 4/5

  • This PR addresses a well-defined bug with a focused solution that maintains system integrity
  • Score reflects solid implementation with comprehensive test coverage, but payments logic is inherently complex
  • Pay close attention to the validation logic in payments.tsx to ensure edge cases are properly handled

Sequence Diagram

sequenceDiagram
    participant User
    participant "Test Suite" as Test
    participant "getItemQuantityForCustomer" as GetQty
    participant "getSubscriptions" as GetSubs
    participant "Mock Prisma" as Prisma
    participant "Mock Tenancy" as Tenancy

    User->>Test: "Run ungrouped include-by-default test"
    Test->>Tenancy: "createMockTenancy with ungrouped offer"
    Tenancy-->>Test: "tenancy config with ungrouped include-by-default offer"
    
    Test->>Prisma: "createMockPrisma with empty subscription findMany"
    Prisma-->>Test: "mock prisma returning []"
    
    Test->>GetQty: "getItemQuantityForCustomer(prisma, tenancy, itemId, customerId, customerType)"
    GetQty->>GetSubs: "getSubscriptions(prisma, tenancy, customerType, customerId)"
    
    GetSubs->>Prisma: "subscription.findMany() for db subscriptions"
    Prisma-->>GetSubs: "empty array []"
    
    GetSubs->>GetSubs: "Process ungrouped defaults with prices='include-by-default'"
    GetSubs->>GetSubs: "Filter ungrouped offers with include-by-default pricing"
    GetSubs->>GetSubs: "Add ungrouped default subscription to list"
    GetSubs-->>GetQty: "subscriptions array with ungrouped default"
    
    GetQty->>GetQty: "Process subscription included items"
    GetQty->>GetQty: "Calculate item quantity: 5 * 1 = 5"
    GetQty->>GetQty: "Add transaction to ledger"
    GetQty->>GetQty: "computeLedgerBalanceAtNow(transactions, now)"
    GetQty-->>Test: "quantity: 5"
    
    Test->>Test: "expect(qty).toBe(5)"
    Test-->>User: "Test passes ✓"
Loading

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on 04cc7a3..a914562

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (1)

apps/backend/src/lib/payments.tsx

⏭️ Files skipped (1)
  Locations  
apps/backend/src/lib/payments.test.tsx

- Resolved merge conflicts in apps/backend/src/lib/payments.tsx
- Updated terminology from offers/groups to products/catalogs
- Fixed TypeScript errors in payments.test.tsx
- All linting and type checks pass
Base automatically changed from payments-redirect-url to dev October 6, 2025 21:34
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Oct 6, 2025
@BilalG1 BilalG1 merged commit f146ff2 into dev Oct 7, 2025
19 checks passed
@BilalG1 BilalG1 deleted the fix-ungrouped-include-by-default branch October 7, 2025 16:19
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