import { getUserIdFromSession } from '../../../utils/auth'; import { REWARDS } from '../../../utils/economy'; import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); interface CompletionResponse { message: string; reward: { coins: number; exp: number; // Added }; updatedCoins: number; updatedExp: number; // Added } /** * 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 jsDayOfWeek = today.getDay(); // 0 (Sunday) to 6 (Saturday) // Convert JS day (Sun=0) to the application's convention (Mon=0, Sun=6) const appDayOfWeek = (jsDayOfWeek === 0) ? 6 : jsDayOfWeek - 1; if (!(habit.daysOfWeek as number[]).includes(appDayOfWeek)) { 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 = REWARDS.HABITS.COMPLETION.coins; const rewardExp = REWARDS.HABITS.COMPLETION.exp; // Added const village = await prisma.village.findUnique({ where: { userId } }); 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, }, exp: { // Added increment: rewardExp, // Added }, }, }), ...(village ? [prisma.villageEvent.create({ data: { villageId: village.id, type: 'HABIT_COMPLETION', message: `Completed habit: "${habit.name}"`, coins: rewardCoins, exp: rewardExp, // Changed from 0 to rewardExp } })] : []), ]); return { message: 'Habit completed successfully!', reward: { coins: rewardCoins, exp: rewardExp, // Added }, updatedCoins: updatedUser.coins, updatedExp: updatedUser.exp, // Added }; });