import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/db' import { getSession, isServerAdmin } from '@/lib/auth' import { sendEmail, getSmtpConfig } from '@/lib/email' import { z } from 'zod' const processSchema = z.object({ action: z.enum(['approve', 'reject']), adminNote: z.string().max(500).optional(), // Only for approve: override limits maxUsers: z.number().min(1).max(1000).optional(), maxProjects: z.number().min(1).max(10000).optional(), }) // PATCH: Approve or reject an upgrade request (SERVER_ADMIN only) export async function PATCH( req: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params const user = await getSession() if (!user || !isServerAdmin(user.role)) { return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 }) } const body = await req.json() const validated = processSchema.safeParse(body) if (!validated.success) { return NextResponse.json({ error: 'Ungültige Eingabe', details: validated.error.flatten() }, { status: 400 }) } // Get the request const upgradeReq = await (prisma as any).upgradeRequest.findUnique({ where: { id }, include: { tenant: { select: { id: true, name: true, plan: true, contactEmail: true } }, requestedBy: { select: { name: true, email: true } }, }, }) if (!upgradeReq) { return NextResponse.json({ error: 'Anfrage nicht gefunden' }, { status: 404 }) } if (upgradeReq.status !== 'PENDING') { return NextResponse.json({ error: 'Anfrage wurde bereits bearbeitet' }, { status: 400 }) } const planLabels: Record = { FREE: 'Free', PRO: 'Pro', } const planLimits: Record = { FREE: { maxUsers: 5, maxProjects: 10 }, PRO: { maxUsers: 999, maxProjects: 9999 }, } if (validated.data.action === 'approve') { const limits = planLimits[upgradeReq.requestedPlan] || planLimits.PRO // Update tenant plan await (prisma as any).tenant.update({ where: { id: upgradeReq.tenantId }, data: { plan: upgradeReq.requestedPlan, subscriptionStatus: 'ACTIVE', trialEndsAt: null, maxUsers: validated.data.maxUsers || limits.maxUsers, maxProjects: validated.data.maxProjects || limits.maxProjects, }, }) // Update request status await (prisma as any).upgradeRequest.update({ where: { id }, data: { status: 'APPROVED', adminNote: validated.data.adminNote || null, processedAt: new Date(), processedById: user.id, }, }) // Send approval email to requester const smtpConfig = await getSmtpConfig() if (smtpConfig) { try { await sendEmail( upgradeReq.requestedBy.email, `Upgrade bestätigt — ${planLabels[upgradeReq.requestedPlan]} Plan aktiviert`, `

✓ Upgrade bestätigt

Ihr Upgrade für ${upgradeReq.tenant.name} wurde bestätigt und ist ab sofort aktiv.

Neuer Plan ${planLabels[upgradeReq.requestedPlan]}
Max. Benutzer ${validated.data.maxUsers || limits.maxUsers}
Max. Projekte ${validated.data.maxProjects || limits.maxProjects}
${validated.data.adminNote ? `

Hinweis:
${validated.data.adminNote}

` : ''}

Vielen Dank für Ihr Vertrauen. Bei Fragen stehen wir Ihnen gerne zur Verfügung.


Lageplan — Digitale Lagepläne für die Feuerwehr

` ) } catch (e) { console.error('Failed to send approval email:', e) } } } else { // Reject await (prisma as any).upgradeRequest.update({ where: { id }, data: { status: 'REJECTED', adminNote: validated.data.adminNote || null, processedAt: new Date(), processedById: user.id, }, }) // Send rejection email const smtpConfig = await getSmtpConfig() if (smtpConfig) { try { await sendEmail( upgradeReq.requestedBy.email, `Upgrade-Anfrage — Rückmeldung`, `

Upgrade-Anfrage

Ihre Upgrade-Anfrage für ${upgradeReq.tenant.name} auf den ${planLabels[upgradeReq.requestedPlan]}-Plan konnte leider nicht bestätigt werden.

${validated.data.adminNote ? `

Begründung:
${validated.data.adminNote}

` : ''}

Bei Fragen kontaktieren Sie uns bitte unter app@lageplan.ch. Sie können jederzeit eine neue Anfrage stellen.


Lageplan — Digitale Lagepläne für die Feuerwehr

` ) } catch (e) { console.error('Failed to send rejection email:', e) } } } // Return updated request const updated = await (prisma as any).upgradeRequest.findUnique({ where: { id }, include: { tenant: { select: { name: true, slug: true, plan: true, subscriptionStatus: true } }, requestedBy: { select: { name: true, email: true } }, }, }) return NextResponse.json({ request: updated }) } catch (error) { console.error('Error processing upgrade request:', error) return NextResponse.json({ error: 'Serverfehler' }, { status: 500 }) } }