Files
shop-server/server/src/routes/api/info-page.js
T
@kirill.komarov fe10f25b8c base commit
2026-05-03 19:57:12 +05:00

119 lines
4.6 KiB
JavaScript

import { prisma } from '../../lib/prisma.js'
function validateBlockPayload(body, reply) {
const key = String(body?.key || '').trim()
const title = String(body?.title || '').trim()
const content = String(body?.body || '').trim()
const sort = Number(body?.sort ?? 0)
const published = body?.published === undefined ? true : Boolean(body.published)
if (!key) return reply.code(400).send({ error: 'key обязателен' })
if (!/^[a-z0-9_-]{2,60}$/i.test(key)) {
return reply.code(400).send({ error: 'key должен быть 2-60 символов: буквы, цифры, "_" или "-"' })
}
if (!title) return reply.code(400).send({ error: 'title обязателен' })
if (title.length > 120) return reply.code(400).send({ error: 'title максимум 120 символов' })
if (!content) return reply.code(400).send({ error: 'body обязателен' })
if (content.length > 5000) return reply.code(400).send({ error: 'body максимум 5000 символов' })
if (!Number.isFinite(sort) || Math.abs(sort) > 10_000) return reply.code(400).send({ error: 'Некорректный sort' })
return { key, title, body: content, sort: Math.trunc(sort), published }
}
export async function registerInfoPageRoutes(fastify) {
fastify.get('/api/info-page/blocks', async () => {
const items = await prisma.infoPageBlock.findMany({
where: { published: true },
orderBy: [{ sort: 'asc' }, { createdAt: 'asc' }],
})
return { items }
})
fastify.get(
'/api/admin/info-page/blocks',
{ preHandler: [fastify.verifyAdmin] },
async () => {
const items = await prisma.infoPageBlock.findMany({ orderBy: [{ sort: 'asc' }, { createdAt: 'asc' }] })
return { items }
},
)
fastify.post(
'/api/admin/info-page/blocks',
{ preHandler: [fastify.verifyAdmin] },
async (request, reply) => {
const validated = validateBlockPayload(request.body, reply)
if (!validated) return
try {
const item = await prisma.infoPageBlock.create({ data: validated })
return reply.code(201).send({ item })
} catch {
return reply.code(409).send({ error: 'Блок с таким key уже существует' })
}
},
)
fastify.patch(
'/api/admin/info-page/blocks/:id',
{ preHandler: [fastify.verifyAdmin] },
async (request, reply) => {
const { id } = request.params
const existing = await prisma.infoPageBlock.findUnique({ where: { id } })
if (!existing) return reply.code(404).send({ error: 'Блок не найден' })
const body = request.body ?? {}
const data = {}
if (body.key !== undefined) {
const key = String(body.key || '').trim()
if (!key) return reply.code(400).send({ error: 'key обязателен' })
if (!/^[a-z0-9_-]{2,60}$/i.test(key)) {
return reply.code(400).send({ error: 'key должен быть 2-60 символов: буквы, цифры, "_" или "-"' })
}
data.key = key
}
if (body.title !== undefined) {
const title = String(body.title || '').trim()
if (!title) return reply.code(400).send({ error: 'title обязателен' })
if (title.length > 120) return reply.code(400).send({ error: 'title максимум 120 символов' })
data.title = title
}
if (body.body !== undefined) {
const content = String(body.body || '').trim()
if (!content) return reply.code(400).send({ error: 'body обязателен' })
if (content.length > 5000) return reply.code(400).send({ error: 'body максимум 5000 символов' })
data.body = content
}
if (body.sort !== undefined) {
const sort = Number(body.sort)
if (!Number.isFinite(sort) || Math.abs(sort) > 10_000) return reply.code(400).send({ error: 'Некорректный sort' })
data.sort = Math.trunc(sort)
}
if (body.published !== undefined) {
data.published = Boolean(body.published)
}
try {
const item = await prisma.infoPageBlock.update({ where: { id }, data })
return { item }
} catch {
return reply.code(409).send({ error: 'Блок с таким key уже существует' })
}
},
)
fastify.delete(
'/api/admin/info-page/blocks/:id',
{ preHandler: [fastify.verifyAdmin] },
async (request, reply) => {
const { id } = request.params
try {
await prisma.infoPageBlock.delete({ where: { id } })
return reply.code(204).send()
} catch {
return reply.code(404).send({ error: 'Блок не найден' })
}
},
)
}