64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import { getUserIdFromSession } from '../../utils/auth';
|
|
import { PLANTING_COST, isCropGrown } from '../../utils/village';
|
|
import { CropType } from '@prisma/client';
|
|
|
|
// --- Handler ---
|
|
export default defineEventHandler(async (event) => {
|
|
const userId = await getUserIdFromSession(event);
|
|
const { fieldId, cropType } = await readBody(event);
|
|
|
|
// 1. --- Validation ---
|
|
if (typeof fieldId !== 'number' || !cropType) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Invalid request body. "fieldId" and "cropType" are required.' });
|
|
}
|
|
if (!Object.values(CropType).includes(cropType)) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Invalid crop type.' });
|
|
}
|
|
|
|
// 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 !== null) {
|
|
throw createError({ statusCode: 409, statusMessage: 'A crop is already planted in this field.' });
|
|
}
|
|
|
|
// 3. --- Perform atomic transaction ---
|
|
try {
|
|
const [, updatedField] = await prisma.$transaction([
|
|
prisma.user.update({
|
|
where: { id: userId, coins: { gte: PLANTING_COST } },
|
|
data: { coins: { decrement: PLANTING_COST } },
|
|
}),
|
|
prisma.villageObject.update({
|
|
where: { id: fieldId },
|
|
data: {
|
|
cropType: cropType,
|
|
plantedAt: new Date(),
|
|
},
|
|
}),
|
|
]);
|
|
|
|
return {
|
|
id: updatedField.id,
|
|
type: updatedField.type,
|
|
x: updatedField.x,
|
|
y: updatedField.y,
|
|
cropType: updatedField.cropType,
|
|
isGrown: isCropGrown(updatedField.plantedAt, updatedField.cropType), // will be false
|
|
};
|
|
|
|
} catch (e) {
|
|
throw createError({ statusCode: 402, statusMessage: 'Insufficient coins to plant seeds.' });
|
|
}
|
|
});
|