11import { NextRequest , NextResponse } from "next/server" ;
22import { getServerSession } from "next-auth" ;
33import { authOptions } from "@/lib/auth" ;
4- import {
5- prisma ,
6- getStripeOrThrow ,
7- getPlanConfig ,
8- isUpgrade ,
9- type PlanType ,
10- } from "@traceroot/core" ;
4+ import { prisma , getStripeOrThrow , getPlanConfig , isUpgrade , type PlanType } from "@traceroot/core" ;
115
126export async function POST ( req : NextRequest ) {
137 try {
@@ -27,10 +21,7 @@ export async function POST(req: NextRequest) {
2721 } ,
2822 } ) ;
2923 if ( ! workspace ) {
30- return NextResponse . json (
31- { error : "Workspace not found" } ,
32- { status : 404 } ,
33- ) ;
24+ return NextResponse . json ( { error : "Workspace not found" } , { status : 404 } ) ;
3425 }
3526
3627 const stripe = getStripeOrThrow ( ) ;
@@ -57,13 +48,12 @@ export async function POST(req: NextRequest) {
5748 }
5849
5950 // First, release any existing schedule
60- const subscription = await stripe . subscriptions . retrieve (
61- workspace . billingSubscriptionId
62- ) ;
51+ const subscription = await stripe . subscriptions . retrieve ( workspace . billingSubscriptionId ) ;
6352 if ( subscription . schedule ) {
64- const scheduleId = typeof subscription . schedule === 'string'
65- ? subscription . schedule
66- : subscription . schedule . id ;
53+ const scheduleId =
54+ typeof subscription . schedule === "string"
55+ ? subscription . schedule
56+ : subscription . schedule . id ;
6757 await stripe . subscriptionSchedules . release ( scheduleId ) ;
6858 }
6959
@@ -74,22 +64,23 @@ export async function POST(req: NextRequest) {
7464
7565 return NextResponse . json ( {
7666 success : true ,
77- message : "Subscription will be canceled at period end"
67+ message : "Subscription will be canceled at period end" ,
7868 } ) ;
7969 }
8070
8171 // Case 2: No subscription yet = need to go through checkout
8272 if ( ! workspace . billingSubscriptionId ) {
8373 return NextResponse . json (
84- { error : "No subscription. Use checkout endpoint instead." , redirect : "/api/billing/checkout" } ,
74+ {
75+ error : "No subscription. Use checkout endpoint instead." ,
76+ redirect : "/api/billing/checkout" ,
77+ } ,
8578 { status : 400 } ,
8679 ) ;
8780 }
8881
8982 // Case 3: Has subscription, changing to another paid plan
90- const subscription = await stripe . subscriptions . retrieve (
91- workspace . billingSubscriptionId ,
92- ) ;
83+ const subscription = await stripe . subscriptions . retrieve ( workspace . billingSubscriptionId ) ;
9384 const subscriptionItemId = subscription . items . data [ 0 ] . id ;
9485
9586 // If subscription is set to cancel, remove that first
@@ -103,9 +94,10 @@ export async function POST(req: NextRequest) {
10394 // UPGRADE: Immediate change with proration
10495 // First, release any existing schedule (e.g., pending downgrade)
10596 if ( subscription . schedule ) {
106- const scheduleId = typeof subscription . schedule === 'string'
107- ? subscription . schedule
108- : subscription . schedule . id ;
97+ const scheduleId =
98+ typeof subscription . schedule === "string"
99+ ? subscription . schedule
100+ : subscription . schedule . id ;
109101 await stripe . subscriptionSchedules . release ( scheduleId ) ;
110102 }
111103
@@ -141,9 +133,10 @@ export async function POST(req: NextRequest) {
141133 // DOWNGRADE to lower paid plan: Schedule change at period end
142134 // First, release any existing schedule (release just detaches, cancel can affect subscription)
143135 if ( subscription . schedule ) {
144- const scheduleId = typeof subscription . schedule === 'string'
145- ? subscription . schedule
146- : subscription . schedule . id ;
136+ const scheduleId =
137+ typeof subscription . schedule === "string"
138+ ? subscription . schedule
139+ : subscription . schedule . id ;
147140 await stripe . subscriptionSchedules . release ( scheduleId ) ;
148141 }
149142
@@ -155,9 +148,7 @@ export async function POST(req: NextRequest) {
155148 await stripe . subscriptionSchedules . update ( schedule . id , {
156149 phases : [
157150 {
158- items : [
159- { price : subscription . items . data [ 0 ] . price . id , quantity : 1 } ,
160- ] ,
151+ items : [ { price : subscription . items . data [ 0 ] . price . id , quantity : 1 } ] ,
161152 start_date : schedule . phases [ 0 ] . start_date ,
162153 end_date : subscription . current_period_end ,
163154 } ,
@@ -170,14 +161,11 @@ export async function POST(req: NextRequest) {
170161
171162 return NextResponse . json ( {
172163 success : true ,
173- message : "Downgrade scheduled for next billing period"
164+ message : "Downgrade scheduled for next billing period" ,
174165 } ) ;
175166 }
176167 } catch ( error ) {
177168 console . error ( "Change plan error:" , error ) ;
178- return NextResponse . json (
179- { error : "Failed to change plan" } ,
180- { status : 500 } ,
181- ) ;
169+ return NextResponse . json ( { error : "Failed to change plan" } , { status : 500 } ) ;
182170 }
183171}
0 commit comments