-
Notifications
You must be signed in to change notification settings - Fork 469
grant and list product routes #937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit 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)
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. Comment |
There was a problem hiding this 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 |
---|---|---|---|
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
There was a problem hiding this 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
fromif (priceId && product.prices !== "include-by-default")
toif (!priceId && product.prices !== "include-by-default")
to properly auto-select the first available price when nopriceId
is provided - Updated product transformation: The
productToInlineProduct
function now includesserver_only
andincluded_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: {...} }"
14 files reviewed, 2 comments
let selectedPrice: SelectedPrice | undefined = undefined; | ||
if (product.prices !== "include-by-default") { | ||
if (!priceId && product.prices !== "include-by-default") { | ||
selectedPrice = typedValues(product.prices)[0]; | ||
} |
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
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
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.
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 sharedgrantProductToCustomer
function used by both the new API grant route and existing test-mode purchase flow, and adds a newProductAlreadyGranted
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
packages/stack-shared/src/known-errors.tsx
apps/backend/prisma/migrations/20251008182311_api_grant_purchase_source/migration.sql
apps/backend/prisma/schema.prisma
packages/stack-shared/src/schema-fields.ts
apps/backend/src/lib/payments.tsx
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/purchase-session.test.ts
apps/e2e/tests/backend/endpoints/api/v1/payments/products.test.ts
Important
Adds API routes for granting and listing products, refactors logic, and introduces error handling for duplicate grants with comprehensive test coverage.
POST
route inroute.ts
to grant products to customers.GET
route inroute.ts
to list products owned by a customer.grantProductToCustomer
inpayments.tsx
.API_GRANT
as a newPurchaseCreationSource
inschema.prisma
.ProductAlreadyGranted
error inknown-errors.tsx
for duplicate non-stackable product grants.products.test.ts
for stackable vs non-stackable products, inline products, pagination, and customer type validation.purchase-session.test.ts
andvalidate-code.test.ts
for new error handling and logic changes.This description was created by
for 2018b85. You can customize this summary. It will automatically update as commits are pushed.