8000 grant and list product routes by BilalG1 · Pull Request #937 · stack-auth/stack-auth · GitHub
[go: up one dir, main page]

Skip to content

Conversation

BilalG1
Copy link
Collaborator
@BilalG1 BilalG1 commented Oct 8, 2025

High-level PR Summary

This PR adds two new REST API routes for product management: a POST endpoint to grant products directly to customers (users/teams) and a GET endpoint to list products owned by a customer. The implementation introduces a new API_GRANT purchase creation source, refactors product granting logic into a shared grantProductToCustomer function used by both the new API grant route and existing test-mode purchase flow, and adds a new ProductAlreadyGranted error for better handling of duplicate non-stackable product grants. The changes include comprehensive test coverage for various scenarios including stackable vs non-stackable products, inline products, pagination, and customer type validation.

⏱️ Estimated Review Time: 30-90 minutes

💡 Review Order Suggestion
Order File Path
1 packages/stack-shared/src/known-errors.tsx
2 apps/backend/prisma/migrations/20251008182311_api_grant_purchase_source/migration.sql
3 apps/backend/prisma/schema.prisma
4 packages/stack-shared/src/schema-fields.ts
5 apps/backend/src/lib/payments.tsx
6 apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx
7 apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/route.ts
8 apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
9 apps/backend/src/lib/payments.test.tsx
10 apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--purchase-session.test.ts
11 apps/e2e/tests/backend/endpoints/api/v1/payments/purchase-session.test.ts
12 apps/e2e/tests/backend/endpoints/api/v1/payments/products.test.ts

Need help? Join our Discord

Analyze latest changes


Important

Adds API routes for granting and listing products, refactors logic, and introduces error handling for duplicate grants with comprehensive test coverage.

  • API Routes:
    • Adds POST route in route.ts to grant products to customers.
    • Adds GET route in route.ts to list products owned by a customer.
  • Logic Refactoring:
    • Refactors product granting logic into grantProductToCustomer in payments.tsx.
    • Introduces API_GRANT as a new PurchaseCreationSource in schema.prisma.
  • Error Handling:
    • Adds ProductAlreadyGranted error in known-errors.tsx for duplicate non-stackable product grants.
  • Testing:
    • Adds tests in products.test.ts for stackable vs non-stackable products, inline products, pagination, and customer type validation.
    • Updates tests in purchase-session.test.ts and validate-code.test.ts for new error handling and logic changes.

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

Copy link
vercel bot commented Oct 8, 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 9, 2025 0:37am
stack-dashboard Ready Ready Preview Comment Oct 9, 2025 0:37am
stack-demo Ready Ready Preview Comment Oct 9, 2025 0:37am
stack-docs Ready Ready Preview Comment Oct 9, 2025 0:37am

Copy link
Contributor
coderabbitai bot commented Oct 8, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

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

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.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch grant-product-routes

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
@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 aeb2508..6ab4d15

  Severity     Location     Issue     Delete  
High apps/backend/src/lib/payments.tsx:573 No database record created
✅ Files analyzed, no issues (11)

apps/backend/prisma/migrations/20251008182311_api_grant_purchase_source/migration.sql
apps/backend/prisma/schema.prisma
apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx
apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/route.ts
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
apps/backend/src/lib/payments.test.tsx
apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--purchase-session.test.ts
apps/e2e/tests/backend/endpoints/api/v1/payments/products.test.ts
apps/e2e/tests/backend/endpoints/api/v1/payments/purchase-session.test.ts
packages/stack-shared/src/known-errors.tsx
packages/stack-shared/src/schema-fields.ts

@BilalG1 BilalG1 marked this pull request as ready for review October 8, 2025 22:57
Copy link
claude bot commented Oct 8, 2025

Claude finished @BilalG1's task —— View job


I'll analyze this and get back to you.

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 follows up on a previous critical bug fix by implementing proper automatic price selection in the product granting functionality. The changes address the issue where the `grantProductToCustomer` function would return success without creating database records when `priceId` was undefined.

Key Changes Made:

  • Fixed automatic price selection logic: Modified the condition in validatePurchaseSession from if (priceId && product.prices !== "include-by-default") to if (!priceId && product.prices !== "include-by-default") to properly auto-select the first available price when no priceId is provided
  • Updated product transformation: The productToInlineProduct function now includes server_only and included_items fields in API responses
  • Enhanced error handling: Replaced generic error messages with the structured ProductAlreadyGranted error throughout the codebase
  • Test updates: Updated numerous test snapshots and assertions to match the new response formats and error structures

These changes ensure that the API grant endpoints work correctly for products with defined prices, fixing the critical bug where grants would appear successful but not actually create database records. The implementation maintains backward compatibility while providing more structured and informative API responses.

Important Files Changed

Changed Files
Filename Score Overview
apps/backend/src/lib/payments.tsx 5/5 Fixed critical automatic price selection logic and enhanced product transformation functions
apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/route.ts 5/5 New API endpoints for granting and listing products with proper validation and error handling
packages/stack-shared/src/known-errors.tsx 5/5 Added new ProductAlreadyGranted error for structured duplicate product handling
apps/e2e/tests/backend/endpoints/api/v1/payments/products.test.ts 5/5 Comprehensive tests for new product grant and listing API functionality
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts 5/5 Refactored to use centralized productToInlineProduct transformation function
packages/stack-shared/src/schema-fields.ts 5/5 Added stackable field to inline product schema and relaxed server_only validation
apps/backend/src/lib/payments.test.tsx 5/5 Updated tests to use structured ProductAlreadyGranted error instead of strings
apps/backend/prisma/schema.prisma 5/5 Added API_GRANT value to PurchaseCreationSource enum for tracking grant origins
apps/backend/prisma/migrations/20251008182311_api_grant_purchase_source/migration.sql 5/5 Database migration to support new API_GRANT purchase creation source
apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx 5/5 Refactored to use shared grantProductToCustomer function, eliminating code duplication
apps/e2e/tests/backend/endpoints/api/v1/payments/purchase-session.test.ts 5/5 Updated test assertions to match new structured error response format
apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--purchase-session.test.ts 5/5 Updated error assertion to use structured PRODUCT_ALREADY_GRANTED error format

Confidence score: 5/5

  • This PR successfully addresses the critical bug identified in the previous review and implements proper functionality
  • The automatic price selection logic fix ensures products with prices are correctly granted via API endpoints
  • All test updates are consistent snapshots reflecting the improved API response structure and error handling

Sequence Diagram

sequenceDiagram
    participant User
    participant API as "REST API"
    participant Handler as "Route Handler"
    participant Validation as "Schema Validation"
    participant PaymentsLib as "Payments Library"
    participant Database as "Prisma Database"
    
    User->>API: "POST /api/latest/payments/products/{customer_type}/{customer_id}"
    API->>Handler: "Route request with auth & body"
    Handler->>Validation: "Validate request schema"
    Validation-->>Handler: "Validated data"
    Handler->>PaymentsLib: "ensureProductIdOrInlineProduct()"
    PaymentsLib-->>Handler: "Product definition"
    Handler->>PaymentsLib: "grantProductToCustomer()"
    PaymentsLib->>PaymentsLib: "validatePurchaseSession()"
    PaymentsLib->>Database: "Check existing purchases"
    Database-->>PaymentsLib: "Purchase data"
    PaymentsLib->>Database: "Create subscription/purchase record"
    Database-->>PaymentsLib: "Created record"
    PaymentsLib-->>Handler: "Grant result"
    Handler-->>API: "Success response"
    API-->>User: "{ success: true }"
    
    User->>API: "GET /api/latest/payments/products/{customer_type}/{customer_id}"
    API->>Handler: "Route request with auth"
    Handler->>PaymentsLib: "getOwnedProductsForCustomer()"
    PaymentsLib->>Database: "Query subscriptions & purchases"
    Database-->>PaymentsLib: "Customer products"
    PaymentsLib->>PaymentsLib: "Apply pagination logic"
    PaymentsLib-->>Handler: "Paginated product list"
    Handler-->>API: "Products response"
    API-->>User: "{ items: [...], pagination: {...} }"
Loading

14 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 418 to +437
let selectedPrice: SelectedPrice | undefined = undefined;
if (product.prices !== "include-by-default") {
if (!priceId && product.prices !== "include-by-default") {
selectedPrice = typedValues(product.prices)[0];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: automatic price selection when no priceId is provided - this defaults to the first price which may not be deterministic if price order changes

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/lib/payments.tsx
Line: 434:437

Comment:
**style:** automatic price selection when no priceId is provided - this defaults to the first price which may not be deterministic if price order changes

How can I resolve this? If you propose a fix, please make it concise.

@@ -0,0 +1,160 @@
import { ensureProductIdOrInlineProduct, getOwnedProductsForCustomer, grantProductToCustomer, productToInlineProduct } from "@/lib/payments";
import { getStripeForAccount } from "@/lib/stripe";
Copy link
Contributor

Choose a reason for hiding this comment

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

style: getStripeForAccount is imported but never used in this file

Suggested change
import { getStripeForAccount } from "@/lib/stripe";
import { ensureProductIdOrInlineProduct, getOwnedProductsForCustomer, grantProductToCustomer, productToInlineProduct } from "@/lib/payments";
import { getPrismaClientForTenancy } from "@/prisma-client";
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
import { adaptSchema, clientOrHigherAuthTypeSchema, inlineProductSchema, productSchema, serverOrHigherAuthTypeSchema, yupArray, yupBoolean, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
import { KnownErrors } from "@stackframe/stack-shared";
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/backend/src/app/api/latest/payments/products/[customer_type]/[customer_id]/route.ts
Line: 2:2

Comment:
**style:** `getStripeForAccount` is imported but never used in this file

```suggestion
import { ensureProductIdOrInlineProduct, getOwnedProductsForCustomer, grantProductToCustomer, productToInlineProduct } from "@/lib/payments";
import { getPrismaClientForTenancy } from "@/prisma-client";
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
import { adaptSchema, clientOrHigherAuthTypeSchema, inlineProductSchema, productSchema, serverOrHigherAuthTypeSchema, yupArray, yupBoolean, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
import { KnownErrors } from "@stackframe/stack-shared";
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
```

How can I resolve this? If you propose a fix, please make it concise.

@BilalG1 BilalG1 requested a review from N2D4 October 8, 2025 23:19
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Oct 8, 2025
@github-actions github-actions bot assigned BilalG1 and unassigned N2D4 Oct 10, 2025
@BilalG1 BilalG1 closed this Oct 10, 2025
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

0