import { NextResponse } from "next/server"; import { Prisma } from "@prisma/client"; import { prisma } from "../../../../../lib/server/db"; import { isDatabaseConfigured } from "../../../../../lib/server/env"; import { dbUnavailable, forbidden, notFound, rateLimited, unauthorized, } from "../../../../../lib/server/responses"; import { getSessionUser } from "../../../../../lib/server/session"; import { apiRoute } from "../../../../../lib/server/apiRoute"; import { rateLimitKey } from "../../../../../lib/server/rateLimit"; import { readLimitedJson } from "../../../../../lib/server/validation/requestBody"; import { jsonFromZodError } from "../../../../../lib/server/validation/zodHttp"; import { makeCopyRuleBodySchema, publishedRuleDocumentSchema, } from "../../../../../lib/server/validation/createFlowSchemas"; import { findCopiedNameHit, stripCopiedRuleDocument, } from "../../../../../lib/create/copiedRuleDocument"; type RouteContext = { params: Promise<{ id: string }> }; export const POST = apiRoute( "rules.byId.makeCopy", async (request, context) => { if (!isDatabaseConfigured()) { return dbUnavailable(); } const user = await getSessionUser(); if (!user) { return unauthorized(); } const { id } = await context.params; const body = await readLimitedJson(request); if (body.ok === false) return body.response; const parsed = makeCopyRuleBodySchema.safeParse(body.value); if (!parsed.success) return jsonFromZodError(parsed.error); const rl = rateLimitKey(`rule-make-copy:${user.id}:${id}`, 60_000); if (rl.ok === false) { return rateLimited(rl.retryAfterMs); } const stakeholder = await prisma.ruleStakeholder.findFirst({ where: { ruleId: id, userId: user.id }, select: { id: true, rule: { select: { id: true, title: true, document: true, userId: true, }, }, }, }); if (!stakeholder) { return notFound(); } if (stakeholder.rule.userId === user.id) { return forbidden(); } const stripped = stripCopiedRuleDocument(stakeholder.rule.document); const documentParsed = publishedRuleDocumentSchema.safeParse(stripped); if (!documentParsed.success) { return jsonFromZodError(documentParsed.error); } const copiedNameHit = findCopiedNameHit( documentParsed.data, stakeholder.rule.title, ); const newRule = await prisma.publishedRule.create({ data: { userId: user.id, title: parsed.data.title, summary: null, document: documentParsed.data as Prisma.InputJsonValue, }, }); return NextResponse.json({ rule: { id: newRule.id, title: newRule.title, summary: newRule.summary, document: documentParsed.data, copiedFromTitle: stakeholder.rule.title, copiedNameHit, createdAt: newRule.createdAt, updatedAt: newRule.updatedAt, }, }); }, );