73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import { getUserIdFromSession } from '../../utils/auth';
|
|
import { CROP_HARVEST_REWARD, isCropGrown } from '../../utils/village';
|
|
import { CropType } from '@prisma/client';
|
|
|
|
// --- Handler ---
|
|
export default defineEventHandler(async (event) => {
|
|
const userId = await getUserIdFromSession(event);
|
|
const { fieldId } = await readBody(event);
|
|
|
|
// 1. --- Validation ---
|
|
if (typeof fieldId !== 'number') {
|
|
throw createError({ statusCode: 400, statusMessage: 'Invalid request body. "fieldId" is required.' });
|
|
}
|
|
|
|
// 2. --- Find the target field and validate its state ---
|
|
const field = await prisma.villageObject.findFirst({
|
|
where: {
|
|
id: fieldId,
|
|
type: 'FIELD',
|
|
village: { userId: userId }, // Ensures ownership
|
|
},
|
|
});
|
|
|
|
if (!field) {
|
|
throw createError({ statusCode: 404, statusMessage: 'Field not found or you do not own it.' });
|
|
}
|
|
|
|
if (!field.cropType || !field.plantedAt) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Nothing is planted in this field.' });
|
|
}
|
|
|
|
if (!isCropGrown(field.plantedAt, field.cropType)) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Crop is not yet fully grown.' });
|
|
}
|
|
|
|
// 3. --- Grant rewards and clear field in a transaction ---
|
|
const reward = CROP_HARVEST_REWARD[field.cropType];
|
|
|
|
const [, , updatedField] = await prisma.$transaction([
|
|
// Grant EXP and Coins
|
|
prisma.user.update({
|
|
where: { id: userId },
|
|
data: {
|
|
exp: { increment: reward.exp },
|
|
coins: { increment: reward.coins },
|
|
},
|
|
}),
|
|
// Clear the crop from the field
|
|
prisma.villageObject.update({
|
|
where: { id: fieldId },
|
|
data: {
|
|
cropType: null,
|
|
plantedAt: null,
|
|
},
|
|
}),
|
|
// Re-fetch the field to return its cleared state
|
|
prisma.villageObject.findUniqueOrThrow({ where: { id: fieldId } }),
|
|
]);
|
|
|
|
return {
|
|
message: `${field.cropType} harvested successfully!`,
|
|
reward: reward,
|
|
updatedField: {
|
|
id: updatedField.id,
|
|
type: updatedField.type,
|
|
x: updatedField.x,
|
|
y: updatedField.y,
|
|
cropType: updatedField.cropType,
|
|
isGrown: false,
|
|
}
|
|
};
|
|
});
|