2025-05-26 17:20:53 +03:00
import { auth } from '$lib/auth' ;
import { error , json } from '@sveltejs/kit' ;
import { db } from '$lib/server/db' ;
import { user , promoCode , promoCodeRedemption } from '$lib/server/db/schema' ;
import { eq , and , count } from 'drizzle-orm' ;
import type { RequestHandler } from './$types' ;
export const POST : RequestHandler = async ( { request } ) = > {
const session = await auth . api . getSession ( { headers : request.headers } ) ;
if ( ! session ? . user ) {
throw error ( 401 , 'Not authenticated' ) ;
}
const { code } = await request . json ( ) ;
if ( ! code || typeof code !== 'string' || code . trim ( ) . length === 0 ) {
return json ( { error : 'Promo code is required' } , { status : 400 } ) ;
}
const normalizedCode = code . trim ( ) . toUpperCase ( ) ;
const userId = Number ( session . user . id ) ;
return await db . transaction ( async ( tx ) = > {
const [ promoData ] = await tx
. select ( {
id : promoCode.id ,
code : promoCode.code ,
rewardAmount : promoCode.rewardAmount ,
maxUses : promoCode.maxUses ,
expiresAt : promoCode.expiresAt ,
isActive : promoCode.isActive ,
description : promoCode.description
} )
. from ( promoCode )
. where ( eq ( promoCode . code , normalizedCode ) )
2025-05-31 12:56:38 +03:00
. for ( 'update' )
2025-05-26 17:20:53 +03:00
. limit ( 1 ) ;
if ( ! promoData ) {
return json ( { error : 'Invalid promo code' } , { status : 400 } ) ;
}
if ( ! promoData . isActive ) {
return json ( { error : 'This promo code is no longer active' } , { status : 400 } ) ;
}
if ( promoData . expiresAt && new Date ( ) > promoData . expiresAt ) {
return json ( { error : 'This promo code has expired' } , { status : 400 } ) ;
}
const [ existingRedemption ] = await tx
. select ( { id : promoCodeRedemption.id } )
. from ( promoCodeRedemption )
. where ( and (
eq ( promoCodeRedemption . userId , userId ) ,
eq ( promoCodeRedemption . promoCodeId , promoData . id )
) )
. limit ( 1 ) ;
if ( existingRedemption ) {
return json ( { error : 'You have already used this promo code' } , { status : 400 } ) ;
}
if ( promoData . maxUses !== null ) {
const [ { totalUses } ] = await tx
. select ( { totalUses : count ( ) } )
. from ( promoCodeRedemption )
2025-05-31 16:45:34 +03:00
. where ( eq ( promoCodeRedemption . promoCodeId , promoData . id ) ) ;
2025-05-26 17:20:53 +03:00
if ( totalUses >= promoData . maxUses ) {
return json ( { error : 'This promo code has reached its usage limit' } , { status : 400 } ) ;
}
}
const [ userData ] = await tx
. select ( { baseCurrencyBalance : user.baseCurrencyBalance } )
. from ( user )
. where ( eq ( user . id , userId ) )
2025-05-31 12:56:38 +03:00
. for ( 'update' )
2025-05-26 17:20:53 +03:00
. limit ( 1 ) ;
if ( ! userData ) {
throw error ( 404 , 'User not found' ) ;
}
const currentBalance = Number ( userData . baseCurrencyBalance || 0 ) ;
const rewardAmount = Number ( promoData . rewardAmount ) ;
const newBalance = currentBalance + rewardAmount ;
await tx
. update ( user )
. set ( {
baseCurrencyBalance : newBalance.toFixed ( 8 ) ,
updatedAt : new Date ( )
} )
. where ( eq ( user . id , userId ) ) ;
await tx
. insert ( promoCodeRedemption )
. values ( {
userId ,
promoCodeId : promoData.id ,
rewardAmount : rewardAmount.toFixed ( 8 )
} ) ;
return json ( {
success : true ,
message : promoData.description || ` Promo code redeemed! You received $ ${ rewardAmount . toFixed ( 2 ) } ` ,
rewardAmount ,
newBalance ,
code : promoData.code
} ) ;
} ) ;
} ;