import { getAuthenticatedUserId } from '~/server/utils/auth'; import prisma from '~/server/utils/prisma'; // Ensure prisma is imported const ONBOARDING_REWARD_COINS = 75; interface OnboardingCompletionResponse { message: string; updatedCoins: number; } // Helper to get the start of the day in UTC function getStartOfDay(date: Date): Date { const d = new Date(date); d.setUTCHours(0, 0, 0, 0); return d; } /** * A special endpoint for the onboarding funnel to complete a habit. * This provides a fixed reward and has simpler logic than the main completion endpoint. * ONLY callable by anonymous users. */ export default defineEventHandler(async (event): Promise => { const userId = getAuthenticatedUserId(event); const { habitId } = await readBody(event); // Fetch the full user to check their anonymous status const user = await prisma.user.findUnique({ where: { id: userId }, select: { id: true, isAnonymous: true } }); // Ensure only anonymous users can use this endpoint if (!user || !user.isAnonymous) { throw createError({ statusCode: 403, statusMessage: 'Forbidden: This endpoint is for anonymous onboarding users only.' }); } if (!habitId || typeof habitId !== 'number') { throw createError({ statusCode: 400, statusMessage: 'Invalid habit ID.' }); } const habit = await prisma.habit.findFirst({ where: { id: habitId, userId: userId } }); if (!habit) { throw createError({ statusCode: 404, statusMessage: 'Habit not found for this user.' }); } const startOfToday = getStartOfDay(new Date()); const existingCompletion = await prisma.habitCompletion.findFirst({ where: { habitId: habitId, date: startOfToday, }, }); if (existingCompletion) { throw createError({ statusCode: 409, statusMessage: 'Habit already completed today.' }); } // Use a transaction to ensure both operations succeed or fail together const [, updatedUser] = await prisma.$transaction([ prisma.habitCompletion.create({ data: { habitId: habitId, date: startOfToday, }, }), prisma.user.update({ where: { id: userId }, data: { coins: { increment: ONBOARDING_REWARD_COINS, }, }, }), ]); return { message: 'Onboarding habit completed successfully!', updatedCoins: updatedUser.coins, }; });