import { getUserIdFromSession } from '../../../utils/auth'; interface CompletionResponse { message: string; reward: { coins: number; }; updatedCoins: number; } /** * Creates a Date object for the start of a given day in UTC. * This is duplicated here as per the instruction not to create new shared utilities. */ function getStartOfDay(date: Date): Date { const startOfDay = new Date(date); startOfDay.setUTCHours(0, 0, 0, 0); return startOfDay; } export default defineEventHandler(async (event): Promise => { const userId = await getUserIdFromSession(event); const habitId = parseInt(event.context.params?.id || '', 10); if (isNaN(habitId)) { throw createError({ statusCode: 400, statusMessage: 'Invalid habit ID.' }); } const habit = await prisma.habit.findFirst({ where: { id: habitId, userId }, }); if (!habit) { throw createError({ statusCode: 404, statusMessage: 'Habit not found.' }); } const today = new Date(); const dayOfWeek = today.getDay(); // 0 (Sunday) to 6 (Saturday) if (!(habit.daysOfWeek as number[]).includes(dayOfWeek)) { throw createError({ statusCode: 400, statusMessage: 'Habit is not active today.' }); } // Normalize date to the beginning of the day for consistent checks const startOfToday = getStartOfDay(new Date()); // Correctly get a Date object const existingCompletion = await prisma.habitCompletion.findFirst({ where: { habitId: habitId, date: startOfToday, // Use precise equality check }, }); if (existingCompletion) { throw createError({ statusCode: 409, statusMessage: 'Habit already completed today.' }); } const rewardCoins = 3; const [, updatedUser] = await prisma.$transaction([ prisma.habitCompletion.create({ data: { habitId: habitId, date: startOfToday, // Save the normalized date }, }), prisma.user.update({ where: { id: userId }, data: { coins: { increment: rewardCoins, }, }, }), ]); return { message: 'Habit completed successfully!', reward: { coins: rewardCoins, }, updatedCoins: updatedUser.coins, }; });