77 lines
3.3 KiB
JavaScript
77 lines
3.3 KiB
JavaScript
import { prisma } from '../lib/prisma.js'
|
|
|
|
export async function registerUserCartRoutes(fastify) {
|
|
fastify.get('/api/me/cart', { preHandler: [fastify.authenticate] }, async (request) => {
|
|
const userId = request.user.sub
|
|
const items = await prisma.cartItem.findMany({
|
|
where: { userId },
|
|
include: { product: { include: { category: true, images: { orderBy: { sort: 'asc' } } } } },
|
|
orderBy: { createdAt: 'asc' },
|
|
})
|
|
return {
|
|
items: items.map((x) => ({
|
|
id: x.id,
|
|
qty: x.qty,
|
|
product: x.product,
|
|
})),
|
|
}
|
|
})
|
|
|
|
fastify.post('/api/me/cart/items', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
|
const userId = request.user.sub
|
|
const productId = String(request.body?.productId || '').trim()
|
|
const qtyRaw = request.body?.qty
|
|
const qty = qtyRaw === undefined || qtyRaw === null || qtyRaw === '' ? 1 : Number(qtyRaw)
|
|
|
|
if (!productId) return reply.code(400).send({ error: 'productId обязателен' })
|
|
if (!Number.isFinite(qty) || qty <= 0) return reply.code(400).send({ error: 'qty должен быть > 0' })
|
|
|
|
const product = await prisma.product.findFirst({ where: { id: productId, published: true } })
|
|
if (!product) return reply.code(404).send({ error: 'Товар не найден' })
|
|
|
|
const available = product.quantity
|
|
const existing = await prisma.cartItem.findUnique({ where: { userId_productId: { userId, productId } } })
|
|
const nextQty = (existing?.qty ?? 0) + Math.floor(qty)
|
|
if (nextQty > available) return reply.code(409).send({ error: `Доступно: ${available} шт.` })
|
|
|
|
const item = await prisma.cartItem.upsert({
|
|
where: { userId_productId: { userId, productId } },
|
|
update: { qty: nextQty },
|
|
create: { userId, productId, qty: nextQty },
|
|
})
|
|
return reply.code(201).send({ item })
|
|
})
|
|
|
|
fastify.patch('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
|
const userId = request.user.sub
|
|
const { id } = request.params
|
|
const qtyRaw = request.body?.qty
|
|
const qty = Number(qtyRaw)
|
|
if (!Number.isFinite(qty) || qty < 0) return reply.code(400).send({ error: 'qty должен быть ≥ 0' })
|
|
|
|
const existing = await prisma.cartItem.findFirst({ where: { id, userId }, include: { product: true } })
|
|
if (!existing) return reply.code(404).send({ error: 'Позиция корзины не найдена' })
|
|
|
|
if (qty === 0) {
|
|
await prisma.cartItem.delete({ where: { id } })
|
|
return reply.code(204).send()
|
|
}
|
|
|
|
const available = existing.product.quantity
|
|
const nextQty = Math.floor(qty)
|
|
if (nextQty > available) return reply.code(409).send({ error: `Доступно: ${available} шт.` })
|
|
|
|
const updated = await prisma.cartItem.update({ where: { id }, data: { qty: nextQty } })
|
|
return { item: updated }
|
|
})
|
|
|
|
fastify.delete('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
|
const userId = request.user.sub
|
|
const { id } = request.params
|
|
const existing = await prisma.cartItem.findFirst({ where: { id, userId } })
|
|
if (!existing) return reply.code(404).send({ error: 'Позиция корзины не найдена' })
|
|
await prisma.cartItem.delete({ where: { id } })
|
|
return reply.code(204).send()
|
|
})
|
|
}
|