Skip to content

feat(api): migrate POST /api/stripe/portal/create#499

Open
arpitgupta1214 wants to merge 2 commits intotestfrom
migrate/stripe-group4
Open

feat(api): migrate POST /api/stripe/portal/create#499
arpitgupta1214 wants to merge 2 commits intotestfrom
migrate/stripe-group4

Conversation

@arpitgupta1214
Copy link
Copy Markdown
Collaborator

Adds POST /api/subscriptions/portal-sessions — Stripe billing portal parity for chat's local /api/stripe/portal/create. Pairs with the existing POST /api/subscriptions/sessions to complete chat's stripe-outbound migration (group 4 of the chat→api migration plan).

Derives accountId from validateAuthContext, looks up the Stripe customer via the local billing_customers mirror, returns { id, url }.

Test plan

  • pnpm test — 2380/2380 green
  • pnpm lint:check, pnpm format:check clean
  • Smoke against deployed preview once chat caller cuts over

Adds POST /api/subscriptions/portal-sessions — Stripe billing portal
parity for chat's local /api/stripe/portal/create. Derives accountId
from validateAuthContext, looks up the Stripe customer via the local
billing_customers mirror, returns { id, url }. Pairs with the existing
POST /api/subscriptions/sessions for chat's stripe-outbound migration
(group 4).
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 1, 2026

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

Project Deployment Actions Updated (UTC)
api Ready Ready Preview May 1, 2026 2:16pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Warning

Rate limit exceeded

@arpitgupta1214 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 5 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8165d4ea-7f43-4a64-9a01-9ffc898b3d4e

📥 Commits

Reviewing files that changed from the base of the PR and between 1dad6ed and a326a8b.

⛔ Files ignored due to path filters (12)
  • app/api/stripe/checkout-sessions/__tests__/route.options.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/checkout-sessions/__tests__/route.post.outcomes.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/checkout-sessions/__tests__/route.post.validation.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/checkout-sessions/__tests__/route.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/checkout-sessions/__tests__/routeTestMocks.ts is excluded by !**/__tests__/** and included by app/**
  • app/api/stripe/portal-sessions/__tests__/route.options.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/portal-sessions/__tests__/route.post.outcomes.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/portal-sessions/__tests__/route.post.validation.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/portal-sessions/__tests__/route.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/api/stripe/portal-sessions/__tests__/routeTestMocks.ts is excluded by !**/__tests__/** and included by app/**
  • lib/stripe/__tests__/createSubscriptionSessionHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/stripe/__tests__/validateCreateSubscriptionSessionRequest.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
📒 Files selected for processing (7)
  • app/api/stripe/checkout-sessions/route.ts
  • app/api/stripe/portal-sessions/route.ts
  • lib/stripe/createPortalSession.ts
  • lib/stripe/createPortalSessionHandler.ts
  • lib/stripe/createPortalSessionSchemas.ts
  • lib/stripe/validateCreatePortalSessionRequest.ts
  • lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch migrate/stripe-group4

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
Review rate limit: 0/1 reviews remaining, refill in 24 minutes and 5 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 11 files

Confidence score: 3/5

  • There is a concrete regression risk in lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts: returning null on query errors can mask real Supabase/DB failures as “not linked,” which may lead to incorrect billing flows and harder incident detection.
  • Given the high confidence (9/10) and moderate-high severity (7/10) of that behavior, this sits at some merge risk until error handling distinguishes operational failures from valid empty results.
  • The issue in app/api/subscriptions/portal-sessions/__tests__/route.post.outcomes.test.ts is low-severity and maintainability-focused (file length/style), so it should not block merge by itself.
  • Pay close attention to lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts, app/api/subscriptions/portal-sessions/__tests__/route.post.outcomes.test.ts - error/result semantics in billing lookup and test maintainability limits.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts">

<violation number="1" location="lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts:18">
P1: Do not return `null` on query errors; it conflates failures with "customer not linked" and hides operational errors from callers.</violation>
</file>

<file name="app/api/subscriptions/portal-sessions/__tests__/route.post.outcomes.test.ts">

<violation number="1" location="app/api/subscriptions/portal-sessions/__tests__/route.post.outcomes.test.ts:1">
P3: Custom agent: **Enforce Clear Code Style and Maintainability Practices**

File exceeds the repository’s 100-line limit for maintainability.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant Client
    participant API as API Handler (Subscriptions)
    participant Auth as Auth Service
    participant DB as Supabase (billing_customers)
    participant Stripe as Stripe API

    Note over Client,Stripe: NEW: Create Billing Portal Session Flow

    Client->>API: POST /api/subscriptions/portal-sessions
    API->>API: NEW: validate JSON body (returnUrl)

    API->>Auth: NEW: validateAuthContext()
    alt Auth Success
        Auth-->>API: return accountId
    else Auth Failure
        Auth-->>API: 401 Unauthorized
        API-->>Client: Error response
    end

    API->>DB: NEW: getStripeCustomerIdByAccountId(accountId)
    alt Customer Found
        DB-->>API: return customerId (cus_...)
    else Customer Not Found
        DB-->>API: null
        API-->>Client: 404 No Stripe customer found
    end

    API->>Stripe: NEW: stripe.billingPortal.sessions.create()
    alt Stripe Success
        Stripe-->>API: return { id, url }
        API-->>Client: 200 OK { id, url }
    else Stripe Error / Missing URL
        Stripe-->>API: error
        API-->>Client: 400/500 Error response
    end

    Note over API: All responses include getCorsHeaders()
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.


if (error) {
console.error("Error fetching billing_customers:", error);
return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Do not return null on query errors; it conflates failures with "customer not linked" and hides operational errors from callers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/supabase/billing_customers/getStripeCustomerIdByAccountId.ts, line 18:

<comment>Do not return `null` on query errors; it conflates failures with "customer not linked" and hides operational errors from callers.</comment>

<file context>
@@ -0,0 +1,22 @@
+
+  if (error) {
+    console.error("Error fetching billing_customers:", error);
+    return null;
+  }
+
</file context>

@@ -0,0 +1,119 @@
import "./routeTestMocks";
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Custom agent: Enforce Clear Code Style and Maintainability Practices

File exceeds the repository’s 100-line limit for maintainability.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/api/subscriptions/portal-sessions/__tests__/route.post.outcomes.test.ts, line 1:

<comment>File exceeds the repository’s 100-line limit for maintainability.</comment>

<file context>
@@ -0,0 +1,119 @@
+import "./routeTestMocks";
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+import { NextRequest, NextResponse } from "next/server";
</file context>

Per CHAT_API_MIGRATION_FINDINGS REST cleanup section, the dedicated
endpoints land at the REST-aligned paths from day one:
  /api/subscriptions/sessions         -> /api/stripe/checkout-sessions
  /api/subscriptions/portal-sessions  -> /api/stripe/portal-sessions

Pure path move — no behavior change.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 14 files (changes from recent commits).

Requires human review: Auto-approval blocked by 2 unresolved issues from previous reviews.

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.

1 participant