refactor: extract findUserOrder helper
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { findUserOrder } from '../find-user-order.js'
|
||||
|
||||
describe('findUserOrder', () => {
|
||||
it('returns order when found', async () => {
|
||||
const mockOrder = { id: '1', userId: 'user1' }
|
||||
const prisma = { order: { findFirst: vi.fn().mockResolvedValue(mockOrder) } }
|
||||
const result = await findUserOrder(prisma, '1', 'user1')
|
||||
expect(result).toEqual(mockOrder)
|
||||
expect(prisma.order.findFirst).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ where: { id: '1', userId: 'user1' } }),
|
||||
)
|
||||
})
|
||||
|
||||
it('throws 404 when order not found', async () => {
|
||||
const prisma = { order: { findFirst: vi.fn().mockResolvedValue(null) } }
|
||||
await expect(findUserOrder(prisma, '999', 'user1')).rejects.toMatchObject({ statusCode: 404 })
|
||||
})
|
||||
|
||||
it('passes include option', async () => {
|
||||
const mockOrder = { id: '1', userId: 'user1', items: [] }
|
||||
const prisma = { order: { findFirst: vi.fn().mockResolvedValue(mockOrder) } }
|
||||
const result = await findUserOrder(prisma, '1', 'user1', { items: true })
|
||||
expect(result).toEqual(mockOrder)
|
||||
expect(prisma.order.findFirst).toHaveBeenCalledWith(expect.objectContaining({ include: { items: true } }))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
export async function findUserOrder(prisma, orderId, userId, include = {}) {
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id: orderId, userId },
|
||||
include,
|
||||
})
|
||||
|
||||
if (!order) {
|
||||
throw Object.assign(new Error('Order not found'), { statusCode: 404 })
|
||||
}
|
||||
|
||||
return order
|
||||
}
|
||||
@@ -1,24 +1,31 @@
|
||||
import { NOTIFICATION_EVENTS } from '../../../shared/constants/notification-events.js'
|
||||
import { asyncHandler } from '../lib/async-handler.js'
|
||||
import { findUserOrder } from '../lib/find-user-order.js'
|
||||
import { prisma } from '../lib/prisma.js'
|
||||
|
||||
export async function registerUserMessageRoutes(fastify) {
|
||||
fastify.get('/api/me/orders/:id/messages', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
||||
fastify.get(
|
||||
'/api/me/orders/:id/messages',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({ where: { id, userId } })
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
await findUserOrder(prisma, id, userId)
|
||||
const items = await prisma.orderMessage.findMany({
|
||||
where: { orderId: id },
|
||||
orderBy: { createdAt: 'asc' },
|
||||
})
|
||||
return { items }
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
fastify.post('/api/me/orders/:id/messages', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
||||
fastify.post(
|
||||
'/api/me/orders/:id/messages',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({ where: { id, userId } })
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
await findUserOrder(prisma, id, userId)
|
||||
const text = String(request.body?.text || '').trim()
|
||||
if (!text) return reply.code(400).send({ error: 'Сообщение пустое' })
|
||||
if (text.length > 2000) return reply.code(400).send({ error: 'Сообщение слишком длинное' })
|
||||
@@ -34,7 +41,8 @@ export async function registerUserMessageRoutes(fastify) {
|
||||
})
|
||||
|
||||
return reply.code(201).send({ item: msg })
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
fastify.get('/api/me/messages/unread-count', { preHandler: [fastify.authenticate] }, async (request) => {
|
||||
const userId = request.user.sub
|
||||
@@ -116,11 +124,13 @@ export async function registerUserMessageRoutes(fastify) {
|
||||
return { items }
|
||||
})
|
||||
|
||||
fastify.post('/api/me/orders/:id/messages/read', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
||||
fastify.post(
|
||||
'/api/me/orders/:id/messages/read',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({ where: { id, userId } })
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
await findUserOrder(prisma, id, userId)
|
||||
|
||||
const now = new Date()
|
||||
await prisma.userOrderMessageReadState.upsert({
|
||||
@@ -129,5 +139,6 @@ export async function registerUserMessageRoutes(fastify) {
|
||||
update: { lastReadAt: now },
|
||||
})
|
||||
return { ok: true }
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NOTIFICATION_EVENTS } from '../../../shared/constants/notification-events.js'
|
||||
import { asyncHandler } from '../lib/async-handler.js'
|
||||
import { isDeliveryCarrier } from '../lib/delivery-carrier.js'
|
||||
import { findUserOrder } from '../lib/find-user-order.js'
|
||||
import { prisma } from '../lib/prisma.js'
|
||||
|
||||
export async function registerUserOrderRoutes(fastify) {
|
||||
@@ -207,11 +208,10 @@ export async function registerUserOrderRoutes(fastify) {
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id, userId },
|
||||
include: { items: true, messages: { orderBy: { createdAt: 'asc' } } },
|
||||
const order = await findUserOrder(prisma, id, userId, {
|
||||
items: true,
|
||||
messages: { orderBy: { createdAt: 'asc' } },
|
||||
})
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
return { item: order }
|
||||
}),
|
||||
)
|
||||
@@ -219,14 +219,10 @@ export async function registerUserOrderRoutes(fastify) {
|
||||
fastify.get(
|
||||
'/api/me/orders/:id/review-eligibility',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
async (request, reply) => {
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id, userId },
|
||||
include: { items: true },
|
||||
})
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
const order = await findUserOrder(prisma, id, userId, { items: true })
|
||||
if (order.status !== 'DONE') {
|
||||
return { canReview: false, items: [] }
|
||||
}
|
||||
@@ -253,7 +249,7 @@ export async function registerUserOrderRoutes(fastify) {
|
||||
hasReview: reviewed.has(x.productId),
|
||||
})),
|
||||
}
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
fastify.post(
|
||||
@@ -262,8 +258,7 @@ export async function registerUserOrderRoutes(fastify) {
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { id } = request.params
|
||||
const order = await prisma.order.findFirst({ where: { id, userId } })
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
const order = await findUserOrder(prisma, id, userId)
|
||||
|
||||
const okDelivery = order.deliveryType === 'delivery' && order.status === 'SHIPPED'
|
||||
const okPickup = order.deliveryType === 'pickup' && order.status === 'READY_FOR_PICKUP'
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { NOTIFICATION_EVENTS } from '../../../shared/constants/notification-events.js'
|
||||
import { asyncHandler } from '../lib/async-handler.js'
|
||||
import { findUserOrder } from '../lib/find-user-order.js'
|
||||
import { prisma } from '../lib/prisma.js'
|
||||
import { createPayment, buildReceipt, getPayment } from '../lib/yookassa.js'
|
||||
|
||||
export async function registerUserPaymentRoutes(fastify) {
|
||||
fastify.post('/api/me/orders/:id/pay', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
||||
fastify.post(
|
||||
'/api/me/orders/:id/pay',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const userEmail = request.user.email
|
||||
|
||||
@@ -13,11 +18,7 @@ export async function registerUserPaymentRoutes(fastify) {
|
||||
|
||||
const { id } = request.params
|
||||
|
||||
const order = await prisma.order.findFirst({
|
||||
where: { id, userId },
|
||||
include: { items: true },
|
||||
})
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
const order = await findUserOrder(prisma, id, userId, { items: true })
|
||||
|
||||
if (order.paymentMethod === 'on_pickup') {
|
||||
return reply.code(409).send({
|
||||
@@ -95,14 +96,17 @@ export async function registerUserPaymentRoutes(fastify) {
|
||||
})
|
||||
|
||||
return { confirmationUrl: result.confirmationUrl }
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
fastify.get('/api/me/orders/:orderId/payment', { preHandler: [fastify.authenticate] }, async (request, reply) => {
|
||||
fastify.get(
|
||||
'/api/me/orders/:orderId/payment',
|
||||
{ preHandler: [fastify.authenticate] },
|
||||
asyncHandler(async (request, reply) => {
|
||||
const userId = request.user.sub
|
||||
const { orderId } = request.params
|
||||
|
||||
const order = await prisma.order.findFirst({ where: { id: orderId, userId } })
|
||||
if (!order) return reply.code(404).send({ error: 'Заказ не найден' })
|
||||
const order = await findUserOrder(prisma, orderId, userId)
|
||||
|
||||
const payment = await prisma.payment.findFirst({
|
||||
where: { orderId },
|
||||
@@ -145,5 +149,6 @@ export async function registerUserPaymentRoutes(fastify) {
|
||||
request.log.error({ err }, '[user-payments] Operation failed')
|
||||
return { status: payment.status, paid: payment.status === 'succeeded' }
|
||||
}
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user