Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | export const dynamic = "force-dynamic"; import { NextRequest, NextResponse } from 'next/server'; import { Session } from "next-auth"; import { prisma } from "@/lib/prisma"; import { redeemPointsSchema } from "@/lib/promotions/validators"; import { withAuth, withErrorHandling, successResponse, ApiSuccessResponse, ApiErrorResponse, ApiError, RouteContext } from "@/lib/api"; interface RedeemPointsData { pointsRedeemed: number; discountValue: number; remainingPoints: number; } /** * POST /api/loyalty/redeem * Redeem loyalty points for discount */ async function handlePost( request: NextRequest, context: RouteContext | undefined, session: Session ): Promise<NextResponse<ApiSuccessResponse<RedeemPointsData> | ApiErrorResponse>> { const userId = session.user.id; const body = await request.json(); // Validate input const validationResult = redeemPointsSchema.safeParse(body); if (!validationResult.success) { throw ApiError.validation("Validation failed", validationResult.error.flatten()); } const { points } = validationResult.data; // Get customer loyalty record const loyalty = await prisma.customerLoyalty.findUnique({ where: { userId }}); if (!loyalty) { throw ApiError.notFound("Loyalty account"); } if (loyalty.totalPoints < points) { throw new ApiError( "INSUFFICIENT_POINTS", "Insufficient points", 400, { available: loyalty.totalPoints, requested: points} ); } // Get active loyalty program for redemption rate const program = await prisma.loyaltyProgram.findFirst({ where: { isActive: true }}); const redemptionRate = program?.redemptionRate || 0.01; const discountValue = points * redemptionRate; // Create redemption transaction and update balance await prisma.$transaction(async (tx) => { await tx.loyaltyTransaction.create({ data: { customerLoyaltyId: loyalty.id, type: "redeem", points: -points, description: `Redeemed ${points} points for $${discountValue.toFixed(2)} discount`}}); await tx.customerLoyalty.update({ where: { id: loyalty.id }, data: { totalPoints: { decrement: points }}}); }); return successResponse({ pointsRedeemed: points, discountValue: Math.round(discountValue * 100) / 100, remainingPoints: loyalty.totalPoints - points}); } export const POST = withErrorHandling(withAuth(handlePost)); |