Alert system
This commit is contained in:
88
app/api/alerts/contacts/[id]/route.ts
Normal file
88
app/api/alerts/contacts/[id]/route.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { requireSession } from "@/lib/auth/requireSession";
|
||||
|
||||
const roleScopeSchema = z.preprocess(
|
||||
(value) => (typeof value === "string" ? value.trim().toUpperCase() : value),
|
||||
z.enum(["MEMBER", "ADMIN", "OWNER", "CUSTOM"])
|
||||
);
|
||||
|
||||
const contactPatchSchema = z.object({
|
||||
name: z.string().trim().min(1).max(120).optional(),
|
||||
roleScope: roleScopeSchema.optional(),
|
||||
email: z.string().trim().email().optional().nullable(),
|
||||
phone: z.string().trim().min(6).max(40).optional().nullable(),
|
||||
userId: z.string().uuid().optional().nullable(),
|
||||
eventTypes: z.array(z.string().trim().min(1)).optional().nullable(),
|
||||
isActive: z.boolean().optional(),
|
||||
});
|
||||
|
||||
function canManageAlerts(role?: string | null) {
|
||||
return role === "OWNER";
|
||||
}
|
||||
|
||||
export async function PATCH(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
const session = await requireSession();
|
||||
if (!session) return NextResponse.json({ ok: false, error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const membership = await prisma.orgUser.findUnique({
|
||||
where: { orgId_userId: { orgId: session.orgId, userId: session.userId } },
|
||||
select: { role: true },
|
||||
});
|
||||
if (!canManageAlerts(membership?.role)) {
|
||||
return NextResponse.json({ ok: false, error: "Forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
const body = await req.json().catch(() => ({}));
|
||||
const parsed = contactPatchSchema.safeParse(body);
|
||||
if (!parsed.success) {
|
||||
return NextResponse.json({ ok: false, error: "Invalid contact payload" }, { status: 400 });
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
const existing = await prisma.alertContact.findFirst({
|
||||
where: { id, orgId: session.orgId },
|
||||
});
|
||||
if (!existing) {
|
||||
return NextResponse.json({ ok: false, error: "Not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const { userId: _userId, eventTypes, ...updateData } = parsed.data;
|
||||
const normalizedEventTypes =
|
||||
eventTypes === null ? Prisma.DbNull : eventTypes ?? undefined;
|
||||
const data = normalizedEventTypes === undefined
|
||||
? updateData
|
||||
: { ...updateData, eventTypes: normalizedEventTypes };
|
||||
const updated = await prisma.alertContact.update({
|
||||
where: { id },
|
||||
data,
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true, contact: updated });
|
||||
}
|
||||
|
||||
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
const session = await requireSession();
|
||||
if (!session) return NextResponse.json({ ok: false, error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const membership = await prisma.orgUser.findUnique({
|
||||
where: { orgId_userId: { orgId: session.orgId, userId: session.userId } },
|
||||
select: { role: true },
|
||||
});
|
||||
if (!canManageAlerts(membership?.role)) {
|
||||
return NextResponse.json({ ok: false, error: "Forbidden" }, { status: 403 });
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
const existing = await prisma.alertContact.findFirst({
|
||||
where: { id, orgId: session.orgId },
|
||||
});
|
||||
if (!existing) {
|
||||
return NextResponse.json({ ok: false, error: "Not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
await prisma.alertContact.delete({ where: { id } });
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
Reference in New Issue
Block a user