Files
shop-server/server/src/routes/user-cart.js
T
2026-05-21 14:22:03 +05:00

97 lines
4.1 KiB
JavaScript

import { prisma } from '../lib/prisma.js'
export async function registerUserCartRoutes(fastify) {
fastify.get('/api/me/cart', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
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,
})),
}
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось загрузить корзину' })
}
})
fastify.post('/api/me/cart/items', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
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 })
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось добавить в корзину' })
}
})
fastify.patch('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
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 }
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось обновить количество' })
}
})
fastify.delete('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => {
try {
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()
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось удалить из корзины' })
}
})
}